teximage.c revision 1f5b1f98468d5e80be39e619ed15c422fbede8d3
1c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)/* 2c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * Mesa 3-D graphics library 3c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * 4c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * 7c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * Permission is hereby granted, free of charge, to any person obtaining a 8c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * copy of this software and associated documentation files (the "Software"), 9c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * to deal in the Software without restriction, including without limitation 10c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * and/or sell copies of the Software, and to permit persons to whom the 12c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * Software is furnished to do so, subject to the following conditions: 13c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * 14c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * The above copyright notice and this permission notice shall be included 15c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * in all copies or substantial portions of the Software. 16c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * 17c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) */ 24c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 25c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 26c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)/** 27c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * \file teximage.c 28c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * Texture image-related functions. 29c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) */ 30c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 31c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include <stdbool.h> 32c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "glheader.h" 33c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "bufferobj.h" 34c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "context.h" 35c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "enums.h" 36c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "fbobject.h" 378abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#include "framebuffer.h" 388abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#include "hash.h" 398abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#include "image.h" 408abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#include "imports.h" 418abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#include "macros.h" 42c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "mfeatures.h" 43c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "state.h" 44c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "texcompress.h" 45c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "teximage.h" 46c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "texobj.h" 47c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "texstate.h" 48c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "texpal.h" 49c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "mtypes.h" 50c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "glformats.h" 51c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 52c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 53c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)/* Inexplicably, GL_HALF_FLOAT_OES has a different value than GL_HALF_FLOAT. 54c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) */ 55c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#ifndef GL_HALF_FLOAT_OES 56c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#define GL_HALF_FLOAT_OES 0x8D61 57c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#endif 58c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 59c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)/** 60c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * State changes which we care about for glCopyTex[Sub]Image() calls. 61c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * In particular, we care about pixel transfer state and buffer state 62c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * (such as glReadBuffer to make sure we read from the right renderbuffer). 63c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) */ 64c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#define NEW_COPY_TEX_STATE (_NEW_BUFFERS | _NEW_PIXEL) 65c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 66c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 67c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 68c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)/** 69c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * Return the simple base format for a given internal texture format. 70c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * For example, given GL_LUMINANCE12_ALPHA4, return GL_LUMINANCE_ALPHA. 71c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * 72c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * \param ctx GL context. 73c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * \param internalFormat the internal texture format token or 1, 2, 3, or 4. 74c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * 75c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * \return the corresponding \u base internal format (GL_ALPHA, GL_LUMINANCE, 76c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA), or -1 if invalid enum. 77c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * 78c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * This is the format which is used during texture application (i.e. the 79c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) * texture format and env mode determine the arithmetic used. 80c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) */ 81c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)GLint 82c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)_mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) 83c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles){ 84c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) switch (internalFormat) { 85c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_ALPHA: 86c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_ALPHA4: 87c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_ALPHA8: 88c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_ALPHA12: 89c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_ALPHA16: 90c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_ALPHA; 91c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case 1: 92c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_LUMINANCE: 93c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_LUMINANCE4: 94c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_LUMINANCE8: 95c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_LUMINANCE12: 96c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_LUMINANCE16: 97c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_LUMINANCE; 98c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case 2: 99c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_LUMINANCE_ALPHA: 100c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_LUMINANCE4_ALPHA4: 101c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_LUMINANCE6_ALPHA2: 102c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_LUMINANCE8_ALPHA8: 103c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_LUMINANCE12_ALPHA4: 104c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_LUMINANCE12_ALPHA12: 105c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_LUMINANCE16_ALPHA16: 106c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_LUMINANCE_ALPHA; 107c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_INTENSITY: 108c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_INTENSITY4: 109c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_INTENSITY8: 110c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_INTENSITY12: 111c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_INTENSITY16: 112c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_INTENSITY; 113c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case 3: 114c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_RGB: 115c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_R3_G3_B2: 116c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_RGB4: 117c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_RGB5: 118c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_RGB8: 119c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_RGB10: 120c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_RGB12: 121c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_RGB16: 122c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_RGB; 123c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case 4: 124c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_RGBA: 125c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_RGBA2: 126c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_RGBA4: 127c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_RGB5_A1: 128c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_RGBA8: 129c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_RGB10_A2: 130c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_RGBA12: 131c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_RGBA16: 132c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_RGBA; 133c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) default: 134c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) ; /* fallthrough */ 135c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } 136c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 137c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) /* GL_BGRA can be an internal format *only* in OpenGL ES (1.x or 2.0). 138c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) */ 139c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) if (_mesa_is_gles(ctx)) { 140c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) switch (internalFormat) { 141c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_BGRA: 142c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_RGBA; 143c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) default: 144c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) ; /* fallthrough */ 145c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } 146c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } 147c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 148c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) if (ctx->Extensions.ARB_ES2_compatibility) { 149c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) switch (internalFormat) { 150c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_RGB565: 151c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_RGB; 152c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) default: 153c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) ; /* fallthrough */ 154c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } 155c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } 156c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 157c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) if (ctx->Extensions.ARB_depth_texture) { 158c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) switch (internalFormat) { 159c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_DEPTH_COMPONENT: 160c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_DEPTH_COMPONENT16: 161c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_DEPTH_COMPONENT24: 162c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_DEPTH_COMPONENT32: 163c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_DEPTH_COMPONENT; 164c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) default: 165c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) ; /* fallthrough */ 166c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } 167c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } 168c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 169c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) switch (internalFormat) { 170c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_COMPRESSED_ALPHA: 171c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_ALPHA; 172c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_COMPRESSED_LUMINANCE: 173c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_LUMINANCE; 174c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_COMPRESSED_LUMINANCE_ALPHA: 175c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_LUMINANCE_ALPHA; 176c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_COMPRESSED_INTENSITY: 177c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_INTENSITY; 178c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_COMPRESSED_RGB: 179c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_RGB; 180c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_COMPRESSED_RGBA: 181c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_RGBA; 182c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) default: 183c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) ; /* fallthrough */ 184c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } 185c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 186c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) if (ctx->Extensions.TDFX_texture_compression_FXT1) { 187c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) switch (internalFormat) { 188c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_COMPRESSED_RGB_FXT1_3DFX: 189c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_RGB; 190c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_COMPRESSED_RGBA_FXT1_3DFX: 191c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_RGBA; 192c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) default: 193c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) ; /* fallthrough */ 194c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } 195c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) } 196c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) 197c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) if (ctx->Extensions.EXT_texture_compression_s3tc) { 198c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) switch (internalFormat) { 199c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 200c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return GL_RGB; 201c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 202 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 203 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: 204 return GL_RGBA; 205 default: 206 ; /* fallthrough */ 207 } 208 } 209 210 if (ctx->Extensions.S3_s3tc) { 211 switch (internalFormat) { 212 case GL_RGB_S3TC: 213 case GL_RGB4_S3TC: 214 return GL_RGB; 215 case GL_RGBA_S3TC: 216 case GL_RGBA4_S3TC: 217 return GL_RGBA; 218 default: 219 ; /* fallthrough */ 220 } 221 } 222 223 if (ctx->Extensions.MESA_ycbcr_texture) { 224 if (internalFormat == GL_YCBCR_MESA) 225 return GL_YCBCR_MESA; 226 } 227 228 if (ctx->Extensions.ARB_texture_float) { 229 switch (internalFormat) { 230 case GL_ALPHA16F_ARB: 231 case GL_ALPHA32F_ARB: 232 return GL_ALPHA; 233 case GL_RGBA16F_ARB: 234 case GL_RGBA32F_ARB: 235 return GL_RGBA; 236 case GL_RGB16F_ARB: 237 case GL_RGB32F_ARB: 238 return GL_RGB; 239 case GL_INTENSITY16F_ARB: 240 case GL_INTENSITY32F_ARB: 241 return GL_INTENSITY; 242 case GL_LUMINANCE16F_ARB: 243 case GL_LUMINANCE32F_ARB: 244 return GL_LUMINANCE; 245 case GL_LUMINANCE_ALPHA16F_ARB: 246 case GL_LUMINANCE_ALPHA32F_ARB: 247 return GL_LUMINANCE_ALPHA; 248 default: 249 ; /* fallthrough */ 250 } 251 } 252 253 if (ctx->Extensions.ATI_envmap_bumpmap) { 254 switch (internalFormat) { 255 case GL_DUDV_ATI: 256 case GL_DU8DV8_ATI: 257 return GL_DUDV_ATI; 258 default: 259 ; /* fallthrough */ 260 } 261 } 262 263 if (ctx->Extensions.EXT_texture_snorm) { 264 switch (internalFormat) { 265 case GL_RED_SNORM: 266 case GL_R8_SNORM: 267 case GL_R16_SNORM: 268 return GL_RED; 269 case GL_RG_SNORM: 270 case GL_RG8_SNORM: 271 case GL_RG16_SNORM: 272 return GL_RG; 273 case GL_RGB_SNORM: 274 case GL_RGB8_SNORM: 275 case GL_RGB16_SNORM: 276 return GL_RGB; 277 case GL_RGBA_SNORM: 278 case GL_RGBA8_SNORM: 279 case GL_RGBA16_SNORM: 280 return GL_RGBA; 281 case GL_ALPHA_SNORM: 282 case GL_ALPHA8_SNORM: 283 case GL_ALPHA16_SNORM: 284 return GL_ALPHA; 285 case GL_LUMINANCE_SNORM: 286 case GL_LUMINANCE8_SNORM: 287 case GL_LUMINANCE16_SNORM: 288 return GL_LUMINANCE; 289 case GL_LUMINANCE_ALPHA_SNORM: 290 case GL_LUMINANCE8_ALPHA8_SNORM: 291 case GL_LUMINANCE16_ALPHA16_SNORM: 292 return GL_LUMINANCE_ALPHA; 293 case GL_INTENSITY_SNORM: 294 case GL_INTENSITY8_SNORM: 295 case GL_INTENSITY16_SNORM: 296 return GL_INTENSITY; 297 default: 298 ; /* fallthrough */ 299 } 300 } 301 302 if (ctx->Extensions.EXT_packed_depth_stencil) { 303 switch (internalFormat) { 304 case GL_DEPTH_STENCIL_EXT: 305 case GL_DEPTH24_STENCIL8_EXT: 306 return GL_DEPTH_STENCIL_EXT; 307 default: 308 ; /* fallthrough */ 309 } 310 } 311 312#if FEATURE_EXT_texture_sRGB 313 if (ctx->Extensions.EXT_texture_sRGB) { 314 switch (internalFormat) { 315 case GL_SRGB_EXT: 316 case GL_SRGB8_EXT: 317 case GL_COMPRESSED_SRGB_EXT: 318 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: 319 return GL_RGB; 320 case GL_SRGB_ALPHA_EXT: 321 case GL_SRGB8_ALPHA8_EXT: 322 case GL_COMPRESSED_SRGB_ALPHA_EXT: 323 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: 324 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: 325 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: 326 return GL_RGBA; 327 case GL_SLUMINANCE_ALPHA_EXT: 328 case GL_SLUMINANCE8_ALPHA8_EXT: 329 case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT: 330 return GL_LUMINANCE_ALPHA; 331 case GL_SLUMINANCE_EXT: 332 case GL_SLUMINANCE8_EXT: 333 case GL_COMPRESSED_SLUMINANCE_EXT: 334 return GL_LUMINANCE; 335 default: 336 ; /* fallthrough */ 337 } 338 } 339#endif /* FEATURE_EXT_texture_sRGB */ 340 341 if (ctx->Version >= 30 || 342 ctx->Extensions.EXT_texture_integer) { 343 switch (internalFormat) { 344 case GL_RGBA8UI_EXT: 345 case GL_RGBA16UI_EXT: 346 case GL_RGBA32UI_EXT: 347 case GL_RGBA8I_EXT: 348 case GL_RGBA16I_EXT: 349 case GL_RGBA32I_EXT: 350 case GL_RGB10_A2UI: 351 return GL_RGBA; 352 case GL_RGB8UI_EXT: 353 case GL_RGB16UI_EXT: 354 case GL_RGB32UI_EXT: 355 case GL_RGB8I_EXT: 356 case GL_RGB16I_EXT: 357 case GL_RGB32I_EXT: 358 return GL_RGB; 359 } 360 } 361 362 if (ctx->Extensions.EXT_texture_integer) { 363 switch (internalFormat) { 364 case GL_ALPHA8UI_EXT: 365 case GL_ALPHA16UI_EXT: 366 case GL_ALPHA32UI_EXT: 367 case GL_ALPHA8I_EXT: 368 case GL_ALPHA16I_EXT: 369 case GL_ALPHA32I_EXT: 370 return GL_ALPHA; 371 case GL_INTENSITY8UI_EXT: 372 case GL_INTENSITY16UI_EXT: 373 case GL_INTENSITY32UI_EXT: 374 case GL_INTENSITY8I_EXT: 375 case GL_INTENSITY16I_EXT: 376 case GL_INTENSITY32I_EXT: 377 return GL_INTENSITY; 378 case GL_LUMINANCE8UI_EXT: 379 case GL_LUMINANCE16UI_EXT: 380 case GL_LUMINANCE32UI_EXT: 381 case GL_LUMINANCE8I_EXT: 382 case GL_LUMINANCE16I_EXT: 383 case GL_LUMINANCE32I_EXT: 384 return GL_LUMINANCE; 385 case GL_LUMINANCE_ALPHA8UI_EXT: 386 case GL_LUMINANCE_ALPHA16UI_EXT: 387 case GL_LUMINANCE_ALPHA32UI_EXT: 388 case GL_LUMINANCE_ALPHA8I_EXT: 389 case GL_LUMINANCE_ALPHA16I_EXT: 390 case GL_LUMINANCE_ALPHA32I_EXT: 391 return GL_LUMINANCE_ALPHA; 392 default: 393 ; /* fallthrough */ 394 } 395 } 396 397 if (ctx->Extensions.ARB_texture_rg) { 398 switch (internalFormat) { 399 case GL_R16F: 400 /* R16F depends on both ARB_half_float_pixel and ARB_texture_float. 401 */ 402 if (!ctx->Extensions.ARB_half_float_pixel) 403 break; 404 /* FALLTHROUGH */ 405 case GL_R32F: 406 if (!ctx->Extensions.ARB_texture_float) 407 break; 408 return GL_RED; 409 case GL_R8I: 410 case GL_R8UI: 411 case GL_R16I: 412 case GL_R16UI: 413 case GL_R32I: 414 case GL_R32UI: 415 if (ctx->Version < 30 && !ctx->Extensions.EXT_texture_integer) 416 break; 417 /* FALLTHROUGH */ 418 case GL_R8: 419 case GL_R16: 420 case GL_RED: 421 case GL_COMPRESSED_RED: 422 return GL_RED; 423 424 case GL_RG16F: 425 /* RG16F depends on both ARB_half_float_pixel and ARB_texture_float. 426 */ 427 if (!ctx->Extensions.ARB_half_float_pixel) 428 break; 429 /* FALLTHROUGH */ 430 case GL_RG32F: 431 if (!ctx->Extensions.ARB_texture_float) 432 break; 433 return GL_RG; 434 case GL_RG8I: 435 case GL_RG8UI: 436 case GL_RG16I: 437 case GL_RG16UI: 438 case GL_RG32I: 439 case GL_RG32UI: 440 if (ctx->Version < 30 && !ctx->Extensions.EXT_texture_integer) 441 break; 442 /* FALLTHROUGH */ 443 case GL_RG: 444 case GL_RG8: 445 case GL_RG16: 446 case GL_COMPRESSED_RG: 447 return GL_RG; 448 default: 449 ; /* fallthrough */ 450 } 451 } 452 453 if (ctx->Extensions.EXT_texture_shared_exponent) { 454 switch (internalFormat) { 455 case GL_RGB9_E5_EXT: 456 return GL_RGB; 457 default: 458 ; /* fallthrough */ 459 } 460 } 461 462 if (ctx->Extensions.EXT_packed_float) { 463 switch (internalFormat) { 464 case GL_R11F_G11F_B10F_EXT: 465 return GL_RGB; 466 default: 467 ; /* fallthrough */ 468 } 469 } 470 471 if (ctx->Extensions.ARB_depth_buffer_float) { 472 switch (internalFormat) { 473 case GL_DEPTH_COMPONENT32F: 474 return GL_DEPTH_COMPONENT; 475 case GL_DEPTH32F_STENCIL8: 476 return GL_DEPTH_STENCIL; 477 default: 478 ; /* fallthrough */ 479 } 480 } 481 482 if (ctx->Extensions.ARB_texture_compression_rgtc) { 483 switch (internalFormat) { 484 case GL_COMPRESSED_RED_RGTC1: 485 case GL_COMPRESSED_SIGNED_RED_RGTC1: 486 return GL_RED; 487 case GL_COMPRESSED_RG_RGTC2: 488 case GL_COMPRESSED_SIGNED_RG_RGTC2: 489 return GL_RG; 490 default: 491 ; /* fallthrough */ 492 } 493 } 494 495 if (ctx->Extensions.EXT_texture_compression_latc) { 496 switch (internalFormat) { 497 case GL_COMPRESSED_LUMINANCE_LATC1_EXT: 498 case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT: 499 return GL_LUMINANCE; 500 case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT: 501 case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT: 502 return GL_LUMINANCE_ALPHA; 503 default: 504 ; /* fallthrough */ 505 } 506 } 507 508 if (ctx->Extensions.ATI_texture_compression_3dc) { 509 switch (internalFormat) { 510 case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI: 511 return GL_LUMINANCE_ALPHA; 512 default: 513 ; /* fallthrough */ 514 } 515 } 516 517 if (ctx->Extensions.OES_compressed_ETC1_RGB8_texture) { 518 switch (internalFormat) { 519 case GL_ETC1_RGB8_OES: 520 return GL_RGB; 521 default: 522 ; /* fallthrough */ 523 } 524 } 525 526 if (ctx->API == API_OPENGLES) { 527 switch (internalFormat) { 528 case GL_PALETTE4_RGB8_OES: 529 case GL_PALETTE4_R5_G6_B5_OES: 530 case GL_PALETTE8_RGB8_OES: 531 case GL_PALETTE8_R5_G6_B5_OES: 532 return GL_RGB; 533 case GL_PALETTE4_RGBA8_OES: 534 case GL_PALETTE8_RGB5_A1_OES: 535 case GL_PALETTE4_RGBA4_OES: 536 case GL_PALETTE4_RGB5_A1_OES: 537 case GL_PALETTE8_RGBA8_OES: 538 case GL_PALETTE8_RGBA4_OES: 539 return GL_RGBA; 540 default: 541 ; /* fallthrough */ 542 } 543 } 544 545 return -1; /* error */ 546} 547 548 549/** 550 * For cube map faces, return a face index in [0,5]. 551 * For other targets return 0; 552 */ 553GLuint 554_mesa_tex_target_to_face(GLenum target) 555{ 556 if (_mesa_is_cube_face(target)) 557 return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; 558 else 559 return 0; 560} 561 562 563 564/** 565 * Install gl_texture_image in a gl_texture_object according to the target 566 * and level parameters. 567 * 568 * \param tObj texture object. 569 * \param target texture target. 570 * \param level image level. 571 * \param texImage texture image. 572 */ 573static void 574set_tex_image(struct gl_texture_object *tObj, 575 GLenum target, GLint level, 576 struct gl_texture_image *texImage) 577{ 578 const GLuint face = _mesa_tex_target_to_face(target); 579 580 ASSERT(tObj); 581 ASSERT(texImage); 582 if (target == GL_TEXTURE_RECTANGLE_NV || target == GL_TEXTURE_EXTERNAL_OES) 583 assert(level == 0); 584 585 tObj->Image[face][level] = texImage; 586 587 /* Set the 'back' pointer */ 588 texImage->TexObject = tObj; 589 texImage->Level = level; 590 texImage->Face = face; 591} 592 593 594/** 595 * Allocate a texture image structure. 596 * 597 * Called via ctx->Driver.NewTextureImage() unless overriden by a device 598 * driver. 599 * 600 * \return a pointer to gl_texture_image struct with all fields initialized to 601 * zero. 602 */ 603struct gl_texture_image * 604_mesa_new_texture_image( struct gl_context *ctx ) 605{ 606 (void) ctx; 607 return CALLOC_STRUCT(gl_texture_image); 608} 609 610 611/** 612 * Free a gl_texture_image and associated data. 613 * This function is a fallback called via ctx->Driver.DeleteTextureImage(). 614 * 615 * \param texImage texture image. 616 * 617 * Free the texture image structure and the associated image data. 618 */ 619void 620_mesa_delete_texture_image(struct gl_context *ctx, 621 struct gl_texture_image *texImage) 622{ 623 /* Free texImage->Data and/or any other driver-specific texture 624 * image storage. 625 */ 626 ASSERT(ctx->Driver.FreeTextureImageBuffer); 627 ctx->Driver.FreeTextureImageBuffer( ctx, texImage ); 628 free(texImage); 629} 630 631 632/** 633 * Test if a target is a proxy target. 634 * 635 * \param target texture target. 636 * 637 * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise. 638 */ 639GLboolean 640_mesa_is_proxy_texture(GLenum target) 641{ 642 /* 643 * NUM_TEXTURE_TARGETS should match number of terms below, except there's no 644 * proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES. 645 */ 646 assert(NUM_TEXTURE_TARGETS == 7 + 2); 647 648 return (target == GL_PROXY_TEXTURE_1D || 649 target == GL_PROXY_TEXTURE_2D || 650 target == GL_PROXY_TEXTURE_3D || 651 target == GL_PROXY_TEXTURE_CUBE_MAP_ARB || 652 target == GL_PROXY_TEXTURE_RECTANGLE_NV || 653 target == GL_PROXY_TEXTURE_1D_ARRAY_EXT || 654 target == GL_PROXY_TEXTURE_2D_ARRAY_EXT); 655} 656 657 658/** 659 * Return the proxy target which corresponds to the given texture target 660 */ 661static GLenum 662get_proxy_target(GLenum target) 663{ 664 switch (target) { 665 case GL_TEXTURE_1D: 666 case GL_PROXY_TEXTURE_1D: 667 return GL_PROXY_TEXTURE_1D; 668 case GL_TEXTURE_2D: 669 case GL_PROXY_TEXTURE_2D: 670 return GL_PROXY_TEXTURE_2D; 671 case GL_TEXTURE_3D: 672 case GL_PROXY_TEXTURE_3D: 673 return GL_PROXY_TEXTURE_3D; 674 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 675 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 676 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 677 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 678 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 679 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 680 case GL_TEXTURE_CUBE_MAP_ARB: 681 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 682 return GL_PROXY_TEXTURE_CUBE_MAP_ARB; 683 case GL_TEXTURE_RECTANGLE_NV: 684 case GL_PROXY_TEXTURE_RECTANGLE_NV: 685 return GL_PROXY_TEXTURE_RECTANGLE_NV; 686 case GL_TEXTURE_1D_ARRAY_EXT: 687 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 688 return GL_PROXY_TEXTURE_1D_ARRAY_EXT; 689 case GL_TEXTURE_2D_ARRAY_EXT: 690 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 691 return GL_PROXY_TEXTURE_2D_ARRAY_EXT; 692 default: 693 _mesa_problem(NULL, "unexpected target in get_proxy_target()"); 694 return 0; 695 } 696} 697 698 699/** 700 * Get the texture object that corresponds to the target of the given 701 * texture unit. The target should have already been checked for validity. 702 * 703 * \param ctx GL context. 704 * \param texUnit texture unit. 705 * \param target texture target. 706 * 707 * \return pointer to the texture object on success, or NULL on failure. 708 */ 709struct gl_texture_object * 710_mesa_select_tex_object(struct gl_context *ctx, 711 const struct gl_texture_unit *texUnit, 712 GLenum target) 713{ 714 const GLboolean arrayTex = (ctx->Extensions.MESA_texture_array || 715 ctx->Extensions.EXT_texture_array); 716 717 switch (target) { 718 case GL_TEXTURE_1D: 719 return texUnit->CurrentTex[TEXTURE_1D_INDEX]; 720 case GL_PROXY_TEXTURE_1D: 721 return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]; 722 case GL_TEXTURE_2D: 723 return texUnit->CurrentTex[TEXTURE_2D_INDEX]; 724 case GL_PROXY_TEXTURE_2D: 725 return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; 726 case GL_TEXTURE_3D: 727 return texUnit->CurrentTex[TEXTURE_3D_INDEX]; 728 case GL_PROXY_TEXTURE_3D: 729 return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]; 730 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 731 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 732 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 733 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 734 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 735 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 736 case GL_TEXTURE_CUBE_MAP_ARB: 737 return ctx->Extensions.ARB_texture_cube_map 738 ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL; 739 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 740 return ctx->Extensions.ARB_texture_cube_map 741 ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL; 742 case GL_TEXTURE_RECTANGLE_NV: 743 return ctx->Extensions.NV_texture_rectangle 744 ? texUnit->CurrentTex[TEXTURE_RECT_INDEX] : NULL; 745 case GL_PROXY_TEXTURE_RECTANGLE_NV: 746 return ctx->Extensions.NV_texture_rectangle 747 ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL; 748 case GL_TEXTURE_1D_ARRAY_EXT: 749 return arrayTex ? texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX] : NULL; 750 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 751 return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL; 752 case GL_TEXTURE_2D_ARRAY_EXT: 753 return arrayTex ? texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX] : NULL; 754 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 755 return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL; 756 case GL_TEXTURE_BUFFER: 757 return ctx->Extensions.ARB_texture_buffer_object 758 ? texUnit->CurrentTex[TEXTURE_BUFFER_INDEX] : NULL; 759 case GL_TEXTURE_EXTERNAL_OES: 760 return ctx->Extensions.OES_EGL_image_external 761 ? texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX] : NULL; 762 default: 763 _mesa_problem(NULL, "bad target in _mesa_select_tex_object()"); 764 return NULL; 765 } 766} 767 768 769/** 770 * Return pointer to texture object for given target on current texture unit. 771 */ 772struct gl_texture_object * 773_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) 774{ 775 struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); 776 return _mesa_select_tex_object(ctx, texUnit, target); 777} 778 779 780/** 781 * Get a texture image pointer from a texture object, given a texture 782 * target and mipmap level. The target and level parameters should 783 * have already been error-checked. 784 * 785 * \param ctx GL context. 786 * \param texObj texture unit. 787 * \param target texture target. 788 * \param level image level. 789 * 790 * \return pointer to the texture image structure, or NULL on failure. 791 */ 792struct gl_texture_image * 793_mesa_select_tex_image(struct gl_context *ctx, 794 const struct gl_texture_object *texObj, 795 GLenum target, GLint level) 796{ 797 const GLuint face = _mesa_tex_target_to_face(target); 798 799 ASSERT(texObj); 800 ASSERT(level >= 0); 801 ASSERT(level < MAX_TEXTURE_LEVELS); 802 803 return texObj->Image[face][level]; 804} 805 806 807/** 808 * Like _mesa_select_tex_image() but if the image doesn't exist, allocate 809 * it and install it. Only return NULL if passed a bad parameter or run 810 * out of memory. 811 */ 812struct gl_texture_image * 813_mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj, 814 GLenum target, GLint level) 815{ 816 struct gl_texture_image *texImage; 817 818 if (!texObj) 819 return NULL; 820 821 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 822 if (!texImage) { 823 texImage = ctx->Driver.NewTextureImage(ctx); 824 if (!texImage) { 825 _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation"); 826 return NULL; 827 } 828 829 set_tex_image(texObj, target, level, texImage); 830 } 831 832 return texImage; 833} 834 835 836/** 837 * Return pointer to the specified proxy texture image. 838 * Note that proxy textures are per-context, not per-texture unit. 839 * \return pointer to texture image or NULL if invalid target, invalid 840 * level, or out of memory. 841 */ 842struct gl_texture_image * 843_mesa_get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level) 844{ 845 struct gl_texture_image *texImage; 846 GLuint texIndex; 847 848 if (level < 0) 849 return NULL; 850 851 switch (target) { 852 case GL_PROXY_TEXTURE_1D: 853 if (level >= ctx->Const.MaxTextureLevels) 854 return NULL; 855 texIndex = TEXTURE_1D_INDEX; 856 break; 857 case GL_PROXY_TEXTURE_2D: 858 if (level >= ctx->Const.MaxTextureLevels) 859 return NULL; 860 texIndex = TEXTURE_2D_INDEX; 861 break; 862 case GL_PROXY_TEXTURE_3D: 863 if (level >= ctx->Const.Max3DTextureLevels) 864 return NULL; 865 texIndex = TEXTURE_3D_INDEX; 866 break; 867 case GL_PROXY_TEXTURE_CUBE_MAP: 868 if (level >= ctx->Const.MaxCubeTextureLevels) 869 return NULL; 870 texIndex = TEXTURE_CUBE_INDEX; 871 break; 872 case GL_PROXY_TEXTURE_RECTANGLE_NV: 873 if (level > 0) 874 return NULL; 875 texIndex = TEXTURE_RECT_INDEX; 876 break; 877 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 878 if (level >= ctx->Const.MaxTextureLevels) 879 return NULL; 880 texIndex = TEXTURE_1D_ARRAY_INDEX; 881 break; 882 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 883 if (level >= ctx->Const.MaxTextureLevels) 884 return NULL; 885 texIndex = TEXTURE_2D_ARRAY_INDEX; 886 break; 887 default: 888 return NULL; 889 } 890 891 texImage = ctx->Texture.ProxyTex[texIndex]->Image[0][level]; 892 if (!texImage) { 893 texImage = ctx->Driver.NewTextureImage(ctx); 894 if (!texImage) { 895 _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); 896 return NULL; 897 } 898 ctx->Texture.ProxyTex[texIndex]->Image[0][level] = texImage; 899 /* Set the 'back' pointer */ 900 texImage->TexObject = ctx->Texture.ProxyTex[texIndex]; 901 } 902 return texImage; 903} 904 905 906/** 907 * Get the maximum number of allowed mipmap levels. 908 * 909 * \param ctx GL context. 910 * \param target texture target. 911 * 912 * \return the maximum number of allowed mipmap levels for the given 913 * texture target, or zero if passed a bad target. 914 * 915 * \sa gl_constants. 916 */ 917GLint 918_mesa_max_texture_levels(struct gl_context *ctx, GLenum target) 919{ 920 switch (target) { 921 case GL_TEXTURE_1D: 922 case GL_PROXY_TEXTURE_1D: 923 case GL_TEXTURE_2D: 924 case GL_PROXY_TEXTURE_2D: 925 return ctx->Const.MaxTextureLevels; 926 case GL_TEXTURE_3D: 927 case GL_PROXY_TEXTURE_3D: 928 return ctx->Const.Max3DTextureLevels; 929 case GL_TEXTURE_CUBE_MAP: 930 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 931 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 932 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 933 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 934 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 935 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 936 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 937 return ctx->Extensions.ARB_texture_cube_map 938 ? ctx->Const.MaxCubeTextureLevels : 0; 939 case GL_TEXTURE_RECTANGLE_NV: 940 case GL_PROXY_TEXTURE_RECTANGLE_NV: 941 return ctx->Extensions.NV_texture_rectangle ? 1 : 0; 942 case GL_TEXTURE_1D_ARRAY_EXT: 943 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 944 case GL_TEXTURE_2D_ARRAY_EXT: 945 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 946 return (ctx->Extensions.MESA_texture_array || 947 ctx->Extensions.EXT_texture_array) 948 ? ctx->Const.MaxTextureLevels : 0; 949 case GL_TEXTURE_BUFFER: 950 return _mesa_is_desktop_gl(ctx) && 951 (ctx->Extensions.ARB_texture_buffer_object || 952 (ctx->Version >= 31)) ? 1 : 0; 953 case GL_TEXTURE_EXTERNAL_OES: 954 /* fall-through */ 955 default: 956 return 0; /* bad target */ 957 } 958} 959 960 961/** 962 * Return number of dimensions per mipmap level for the given texture target. 963 */ 964GLint 965_mesa_get_texture_dimensions(GLenum target) 966{ 967 switch (target) { 968 case GL_TEXTURE_1D: 969 case GL_PROXY_TEXTURE_1D: 970 return 1; 971 case GL_TEXTURE_2D: 972 case GL_TEXTURE_RECTANGLE: 973 case GL_TEXTURE_CUBE_MAP: 974 case GL_PROXY_TEXTURE_2D: 975 case GL_PROXY_TEXTURE_RECTANGLE: 976 case GL_PROXY_TEXTURE_CUBE_MAP: 977 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 978 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 979 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 980 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 981 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 982 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 983 case GL_TEXTURE_1D_ARRAY: 984 case GL_PROXY_TEXTURE_1D_ARRAY: 985 case GL_TEXTURE_EXTERNAL_OES: 986 return 2; 987 case GL_TEXTURE_3D: 988 case GL_PROXY_TEXTURE_3D: 989 case GL_TEXTURE_2D_ARRAY: 990 case GL_PROXY_TEXTURE_2D_ARRAY: 991 return 3; 992 case GL_TEXTURE_BUFFER: 993 /* fall-through */ 994 default: 995 _mesa_problem(NULL, "invalid target 0x%x in get_texture_dimensions()", 996 target); 997 return 2; 998 } 999} 1000 1001 1002 1003 1004#if 000 /* not used anymore */ 1005/* 1006 * glTexImage[123]D can accept a NULL image pointer. In this case we 1007 * create a texture image with unspecified image contents per the OpenGL 1008 * spec. 1009 */ 1010static GLubyte * 1011make_null_texture(GLint width, GLint height, GLint depth, GLenum format) 1012{ 1013 const GLint components = _mesa_components_in_format(format); 1014 const GLint numPixels = width * height * depth; 1015 GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte)); 1016 1017#ifdef DEBUG 1018 /* 1019 * Let's see if anyone finds this. If glTexImage2D() is called with 1020 * a NULL image pointer then load the texture image with something 1021 * interesting instead of leaving it indeterminate. 1022 */ 1023 if (data) { 1024 static const char message[8][32] = { 1025 " X X XXXXX XXX X ", 1026 " XX XX X X X X X ", 1027 " X X X X X X X ", 1028 " X X XXXX XXX XXXXX ", 1029 " X X X X X X ", 1030 " X X X X X X X ", 1031 " X X XXXXX XXX X X ", 1032 " " 1033 }; 1034 1035 GLubyte *imgPtr = data; 1036 GLint h, i, j, k; 1037 for (h = 0; h < depth; h++) { 1038 for (i = 0; i < height; i++) { 1039 GLint srcRow = 7 - (i % 8); 1040 for (j = 0; j < width; j++) { 1041 GLint srcCol = j % 32; 1042 GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70; 1043 for (k = 0; k < components; k++) { 1044 *imgPtr++ = texel; 1045 } 1046 } 1047 } 1048 } 1049 } 1050#endif 1051 1052 return data; 1053} 1054#endif 1055 1056 1057 1058/** 1059 * Set the size and format-related fields of a gl_texture_image struct 1060 * to zero. This is used when a proxy texture test fails. 1061 */ 1062static void 1063clear_teximage_fields(struct gl_texture_image *img) 1064{ 1065 ASSERT(img); 1066 img->_BaseFormat = 0; 1067 img->InternalFormat = 0; 1068 img->Border = 0; 1069 img->Width = 0; 1070 img->Height = 0; 1071 img->Depth = 0; 1072 img->Width2 = 0; 1073 img->Height2 = 0; 1074 img->Depth2 = 0; 1075 img->WidthLog2 = 0; 1076 img->HeightLog2 = 0; 1077 img->DepthLog2 = 0; 1078 img->TexFormat = MESA_FORMAT_NONE; 1079} 1080 1081 1082/** 1083 * Initialize basic fields of the gl_texture_image struct. 1084 * 1085 * \param ctx GL context. 1086 * \param img texture image structure to be initialized. 1087 * \param width image width. 1088 * \param height image height. 1089 * \param depth image depth. 1090 * \param border image border. 1091 * \param internalFormat internal format. 1092 * \param format the actual hardware format (one of MESA_FORMAT_*) 1093 * 1094 * Fills in the fields of \p img with the given information. 1095 * Note: width, height and depth include the border. 1096 */ 1097void 1098_mesa_init_teximage_fields(struct gl_context *ctx, 1099 struct gl_texture_image *img, 1100 GLsizei width, GLsizei height, GLsizei depth, 1101 GLint border, GLenum internalFormat, 1102 gl_format format) 1103{ 1104 GLenum target; 1105 ASSERT(img); 1106 ASSERT(width >= 0); 1107 ASSERT(height >= 0); 1108 ASSERT(depth >= 0); 1109 1110 target = img->TexObject->Target; 1111 img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat ); 1112 ASSERT(img->_BaseFormat > 0); 1113 img->InternalFormat = internalFormat; 1114 img->Border = border; 1115 img->Width = width; 1116 img->Height = height; 1117 img->Depth = depth; 1118 1119 img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */ 1120 img->WidthLog2 = _mesa_logbase2(img->Width2); 1121 1122 switch(target) { 1123 case GL_TEXTURE_1D: 1124 case GL_TEXTURE_BUFFER: 1125 case GL_PROXY_TEXTURE_1D: 1126 if (height == 0) 1127 img->Height2 = 0; 1128 else 1129 img->Height2 = 1; 1130 img->HeightLog2 = 0; 1131 if (depth == 0) 1132 img->Depth2 = 0; 1133 else 1134 img->Depth2 = 1; 1135 img->DepthLog2 = 0; 1136 break; 1137 case GL_TEXTURE_1D_ARRAY: 1138 case GL_PROXY_TEXTURE_1D_ARRAY: 1139 img->Height2 = height; /* no border */ 1140 img->HeightLog2 = 0; /* not used */ 1141 if (depth == 0) 1142 img->Depth2 = 0; 1143 else 1144 img->Depth2 = 1; 1145 img->DepthLog2 = 0; 1146 break; 1147 case GL_TEXTURE_2D: 1148 case GL_TEXTURE_RECTANGLE: 1149 case GL_TEXTURE_CUBE_MAP: 1150 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1151 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1152 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1153 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1154 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1155 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1156 case GL_TEXTURE_EXTERNAL_OES: 1157 case GL_PROXY_TEXTURE_2D: 1158 case GL_PROXY_TEXTURE_RECTANGLE: 1159 case GL_PROXY_TEXTURE_CUBE_MAP: 1160 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 1161 img->HeightLog2 = _mesa_logbase2(img->Height2); 1162 if (depth == 0) 1163 img->Depth2 = 0; 1164 else 1165 img->Depth2 = 1; 1166 img->DepthLog2 = 0; 1167 break; 1168 case GL_TEXTURE_2D_ARRAY: 1169 case GL_PROXY_TEXTURE_2D_ARRAY: 1170 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 1171 img->HeightLog2 = _mesa_logbase2(img->Height2); 1172 img->Depth2 = depth; /* no border */ 1173 img->DepthLog2 = 0; /* not used */ 1174 break; 1175 case GL_TEXTURE_3D: 1176 case GL_PROXY_TEXTURE_3D: 1177 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 1178 img->HeightLog2 = _mesa_logbase2(img->Height2); 1179 img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */ 1180 img->DepthLog2 = _mesa_logbase2(img->Depth2); 1181 break; 1182 default: 1183 _mesa_problem(NULL, "invalid target 0x%x in _mesa_init_teximage_fields()", 1184 target); 1185 } 1186 1187 img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); 1188 img->TexFormat = format; 1189} 1190 1191 1192/** 1193 * Free and clear fields of the gl_texture_image struct. 1194 * 1195 * \param ctx GL context. 1196 * \param texImage texture image structure to be cleared. 1197 * 1198 * After the call, \p texImage will have no data associated with it. Its 1199 * fields are cleared so that its parent object will test incomplete. 1200 */ 1201void 1202_mesa_clear_texture_image(struct gl_context *ctx, 1203 struct gl_texture_image *texImage) 1204{ 1205 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 1206 clear_teximage_fields(texImage); 1207} 1208 1209 1210/** 1211 * This is the fallback for Driver.TestProxyTexImage(). Test the texture 1212 * level, width, height and depth against the ctx->Const limits for textures. 1213 * 1214 * A hardware driver might override this function if, for example, the 1215 * max 3D texture size is 512x512x64 (i.e. not a cube). 1216 * 1217 * Note that width, height, depth == 0 is not an error. However, a 1218 * texture with zero width/height/depth will be considered "incomplete" 1219 * and texturing will effectively be disabled. 1220 * 1221 * \param target one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D, 1222 * GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV, 1223 * GL_PROXY_TEXTURE_CUBE_MAP_ARB. 1224 * \param level as passed to glTexImage 1225 * \param internalFormat as passed to glTexImage 1226 * \param format as passed to glTexImage 1227 * \param type as passed to glTexImage 1228 * \param width as passed to glTexImage 1229 * \param height as passed to glTexImage 1230 * \param depth as passed to glTexImage 1231 * \param border as passed to glTexImage 1232 * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable. 1233 */ 1234GLboolean 1235_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level, 1236 GLint internalFormat, GLenum format, GLenum type, 1237 GLint width, GLint height, GLint depth, GLint border) 1238{ 1239 GLint maxSize; 1240 1241 (void) internalFormat; 1242 (void) format; 1243 (void) type; 1244 1245 switch (target) { 1246 case GL_PROXY_TEXTURE_1D: 1247 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1248 if (width < 2 * border || width > 2 * border + maxSize) 1249 return GL_FALSE; 1250 if (level >= ctx->Const.MaxTextureLevels) 1251 return GL_FALSE; 1252 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1253 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1254 return GL_FALSE; 1255 } 1256 return GL_TRUE; 1257 1258 case GL_PROXY_TEXTURE_2D: 1259 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1260 if (width < 2 * border || width > 2 * border + maxSize) 1261 return GL_FALSE; 1262 if (height < 2 * border || height > 2 * border + maxSize) 1263 return GL_FALSE; 1264 if (level >= ctx->Const.MaxTextureLevels) 1265 return GL_FALSE; 1266 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1267 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1268 return GL_FALSE; 1269 if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) 1270 return GL_FALSE; 1271 } 1272 return GL_TRUE; 1273 1274 case GL_PROXY_TEXTURE_3D: 1275 maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); 1276 if (width < 2 * border || width > 2 * border + maxSize) 1277 return GL_FALSE; 1278 if (height < 2 * border || height > 2 * border + maxSize) 1279 return GL_FALSE; 1280 if (depth < 2 * border || depth > 2 * border + maxSize) 1281 return GL_FALSE; 1282 if (level >= ctx->Const.Max3DTextureLevels) 1283 return GL_FALSE; 1284 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1285 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1286 return GL_FALSE; 1287 if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) 1288 return GL_FALSE; 1289 if (depth > 0 && !_mesa_is_pow_two(depth - 2 * border)) 1290 return GL_FALSE; 1291 } 1292 return GL_TRUE; 1293 1294 case GL_PROXY_TEXTURE_RECTANGLE_NV: 1295 maxSize = ctx->Const.MaxTextureRectSize; 1296 if (width < 0 || width > maxSize) 1297 return GL_FALSE; 1298 if (height < 0 || height > maxSize) 1299 return GL_FALSE; 1300 if (level != 0) 1301 return GL_FALSE; 1302 return GL_TRUE; 1303 1304 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 1305 maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1); 1306 if (width < 2 * border || width > 2 * border + maxSize) 1307 return GL_FALSE; 1308 if (height < 2 * border || height > 2 * border + maxSize) 1309 return GL_FALSE; 1310 if (level >= ctx->Const.MaxCubeTextureLevels) 1311 return GL_FALSE; 1312 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1313 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1314 return GL_FALSE; 1315 if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) 1316 return GL_FALSE; 1317 } 1318 return GL_TRUE; 1319 1320 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 1321 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1322 if (width < 2 * border || width > 2 * border + maxSize) 1323 return GL_FALSE; 1324 if (height < 1 || height > ctx->Const.MaxArrayTextureLayers) 1325 return GL_FALSE; 1326 if (level >= ctx->Const.MaxTextureLevels) 1327 return GL_FALSE; 1328 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1329 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1330 return GL_FALSE; 1331 } 1332 return GL_TRUE; 1333 1334 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1335 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1336 if (width < 2 * border || width > 2 * border + maxSize) 1337 return GL_FALSE; 1338 if (height < 2 * border || height > 2 * border + maxSize) 1339 return GL_FALSE; 1340 if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers) 1341 return GL_FALSE; 1342 if (level >= ctx->Const.MaxTextureLevels) 1343 return GL_FALSE; 1344 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1345 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1346 return GL_FALSE; 1347 if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) 1348 return GL_FALSE; 1349 } 1350 return GL_TRUE; 1351 1352 default: 1353 _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage"); 1354 return GL_FALSE; 1355 } 1356} 1357 1358 1359/** 1360 * Check if the memory used by the texture would exceed the driver's limit. 1361 * This lets us support a max 3D texture size of 8K (for example) but 1362 * prevents allocating a full 8K x 8K x 8K texture. 1363 * XXX this could be rolled into the proxy texture size test (above) but 1364 * we don't have the actual texture internal format at that point. 1365 */ 1366static GLboolean 1367legal_texture_size(struct gl_context *ctx, gl_format format, 1368 GLint width, GLint height, GLint depth) 1369{ 1370 uint64_t bytes = _mesa_format_image_size64(format, width, height, depth); 1371 uint64_t mbytes = bytes / (1024 * 1024); /* convert to MB */ 1372 return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes; 1373} 1374 1375 1376/** 1377 * Return true if the format is only valid for glCompressedTexImage. 1378 */ 1379static GLboolean 1380compressedteximage_only_format(const struct gl_context *ctx, GLenum format) 1381{ 1382 switch (format) { 1383 case GL_ETC1_RGB8_OES: 1384 case GL_PALETTE4_RGB8_OES: 1385 case GL_PALETTE4_RGBA8_OES: 1386 case GL_PALETTE4_R5_G6_B5_OES: 1387 case GL_PALETTE4_RGBA4_OES: 1388 case GL_PALETTE4_RGB5_A1_OES: 1389 case GL_PALETTE8_RGB8_OES: 1390 case GL_PALETTE8_RGBA8_OES: 1391 case GL_PALETTE8_R5_G6_B5_OES: 1392 case GL_PALETTE8_RGBA4_OES: 1393 case GL_PALETTE8_RGB5_A1_OES: 1394 return GL_TRUE; 1395 default: 1396 return GL_FALSE; 1397 } 1398} 1399 1400 1401/** 1402 * Helper function to determine whether a target and specific compression 1403 * format are supported. 1404 */ 1405static GLboolean 1406target_can_be_compressed(const struct gl_context *ctx, GLenum target, 1407 GLenum intFormat) 1408{ 1409 (void) intFormat; /* not used yet */ 1410 1411 switch (target) { 1412 case GL_TEXTURE_2D: 1413 case GL_PROXY_TEXTURE_2D: 1414 return GL_TRUE; /* true for any compressed format so far */ 1415 case GL_PROXY_TEXTURE_CUBE_MAP: 1416 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1417 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1418 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1419 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1420 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1421 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1422 return ctx->Extensions.ARB_texture_cube_map; 1423 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1424 case GL_TEXTURE_2D_ARRAY_EXT: 1425 return (ctx->Extensions.MESA_texture_array || 1426 ctx->Extensions.EXT_texture_array); 1427 default: 1428 return GL_FALSE; 1429 } 1430} 1431 1432 1433/** 1434 * Check if the given texture target value is legal for a 1435 * glTexImage1/2/3D call. 1436 */ 1437static GLboolean 1438legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target) 1439{ 1440 switch (dims) { 1441 case 1: 1442 switch (target) { 1443 case GL_TEXTURE_1D: 1444 case GL_PROXY_TEXTURE_1D: 1445 return _mesa_is_desktop_gl(ctx); 1446 default: 1447 return GL_FALSE; 1448 } 1449 case 2: 1450 switch (target) { 1451 case GL_TEXTURE_2D: 1452 return GL_TRUE; 1453 case GL_PROXY_TEXTURE_2D: 1454 return _mesa_is_desktop_gl(ctx); 1455 case GL_PROXY_TEXTURE_CUBE_MAP: 1456 return _mesa_is_desktop_gl(ctx) 1457 && ctx->Extensions.ARB_texture_cube_map; 1458 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1459 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1460 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1461 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1462 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1463 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1464 return ctx->Extensions.ARB_texture_cube_map; 1465 case GL_TEXTURE_RECTANGLE_NV: 1466 case GL_PROXY_TEXTURE_RECTANGLE_NV: 1467 return _mesa_is_desktop_gl(ctx) 1468 && ctx->Extensions.NV_texture_rectangle; 1469 case GL_TEXTURE_1D_ARRAY_EXT: 1470 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 1471 return _mesa_is_desktop_gl(ctx) 1472 && (ctx->Extensions.MESA_texture_array || 1473 ctx->Extensions.EXT_texture_array); 1474 default: 1475 return GL_FALSE; 1476 } 1477 case 3: 1478 switch (target) { 1479 case GL_TEXTURE_3D: 1480 return GL_TRUE; 1481 case GL_PROXY_TEXTURE_3D: 1482 return _mesa_is_desktop_gl(ctx); 1483 case GL_TEXTURE_2D_ARRAY_EXT: 1484 return (_mesa_is_desktop_gl(ctx) 1485 && (ctx->Extensions.MESA_texture_array || 1486 ctx->Extensions.EXT_texture_array)) 1487 || _mesa_is_gles3(ctx); 1488 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1489 return _mesa_is_desktop_gl(ctx) 1490 && (ctx->Extensions.MESA_texture_array || 1491 ctx->Extensions.EXT_texture_array); 1492 default: 1493 return GL_FALSE; 1494 } 1495 default: 1496 _mesa_problem(ctx, "invalid dims=%u in legal_teximage_target()", dims); 1497 return GL_FALSE; 1498 } 1499} 1500 1501 1502/** 1503 * Check if the given texture target value is legal for a 1504 * glTexSubImage, glCopyTexSubImage or glCopyTexImage call. 1505 * The difference compared to legal_teximage_target() above is that 1506 * proxy targets are not supported. 1507 */ 1508static GLboolean 1509legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target) 1510{ 1511 switch (dims) { 1512 case 1: 1513 return _mesa_is_desktop_gl(ctx) && target == GL_TEXTURE_1D; 1514 case 2: 1515 switch (target) { 1516 case GL_TEXTURE_2D: 1517 return GL_TRUE; 1518 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1519 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1520 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1521 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1522 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1523 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1524 return ctx->Extensions.ARB_texture_cube_map; 1525 case GL_TEXTURE_RECTANGLE_NV: 1526 return _mesa_is_desktop_gl(ctx) 1527 && ctx->Extensions.NV_texture_rectangle; 1528 case GL_TEXTURE_1D_ARRAY_EXT: 1529 return _mesa_is_desktop_gl(ctx) 1530 && (ctx->Extensions.MESA_texture_array || 1531 ctx->Extensions.EXT_texture_array); 1532 default: 1533 return GL_FALSE; 1534 } 1535 case 3: 1536 switch (target) { 1537 case GL_TEXTURE_3D: 1538 return GL_TRUE; 1539 case GL_TEXTURE_2D_ARRAY_EXT: 1540 return (_mesa_is_desktop_gl(ctx) 1541 && (ctx->Extensions.MESA_texture_array || 1542 ctx->Extensions.EXT_texture_array)) 1543 || _mesa_is_gles3(ctx); 1544 default: 1545 return GL_FALSE; 1546 } 1547 default: 1548 _mesa_problem(ctx, "invalid dims=%u in legal_texsubimage_target()", 1549 dims); 1550 return GL_FALSE; 1551 } 1552} 1553 1554 1555/** 1556 * Helper function to determine if a texture object is mutable (in terms 1557 * of GL_ARB_texture_storage). 1558 */ 1559static GLboolean 1560mutable_tex_object(struct gl_context *ctx, GLenum target) 1561{ 1562 if (ctx->Extensions.ARB_texture_storage) { 1563 struct gl_texture_object *texObj = 1564 _mesa_get_current_tex_object(ctx, target); 1565 return !texObj->Immutable; 1566 } 1567 return GL_TRUE; 1568} 1569 1570 1571GLenum 1572_mesa_es_error_check_format_and_type(GLenum format, GLenum type, 1573 unsigned dimensions) 1574{ 1575 bool type_valid = true; 1576 1577 switch (format) { 1578 case GL_ALPHA: 1579 case GL_LUMINANCE: 1580 case GL_LUMINANCE_ALPHA: 1581 type_valid = (type == GL_UNSIGNED_BYTE 1582 || type == GL_FLOAT 1583 || type == GL_HALF_FLOAT_OES); 1584 break; 1585 1586 case GL_RGB: 1587 type_valid = (type == GL_UNSIGNED_BYTE 1588 || type == GL_UNSIGNED_SHORT_5_6_5 1589 || type == GL_FLOAT 1590 || type == GL_HALF_FLOAT_OES); 1591 break; 1592 1593 case GL_RGBA: 1594 type_valid = (type == GL_UNSIGNED_BYTE 1595 || type == GL_UNSIGNED_SHORT_4_4_4_4 1596 || type == GL_UNSIGNED_SHORT_5_5_5_1 1597 || type == GL_FLOAT 1598 || type == GL_HALF_FLOAT_OES 1599 || type == GL_UNSIGNED_INT_2_10_10_10_REV); 1600 break; 1601 1602 case GL_DEPTH_COMPONENT: 1603 /* This format is filtered against invalid dimensionalities elsewhere. 1604 */ 1605 type_valid = (type == GL_UNSIGNED_SHORT 1606 || type == GL_UNSIGNED_INT); 1607 break; 1608 1609 case GL_DEPTH_STENCIL: 1610 /* This format is filtered against invalid dimensionalities elsewhere. 1611 */ 1612 type_valid = (type == GL_UNSIGNED_INT_24_8); 1613 break; 1614 1615 case GL_BGRA_EXT: 1616 type_valid = (type == GL_UNSIGNED_BYTE); 1617 1618 /* This feels like a bug in the EXT_texture_format_BGRA8888 spec, but 1619 * the format does not appear to be allowed for 3D textures in OpenGL 1620 * ES. 1621 */ 1622 if (dimensions != 2) 1623 return GL_INVALID_VALUE; 1624 1625 break; 1626 1627 default: 1628 return GL_INVALID_VALUE; 1629 } 1630 1631 return type_valid ? GL_NO_ERROR : GL_INVALID_OPERATION; 1632} 1633 1634/** 1635 * Test the glTexImage[123]D() parameters for errors. 1636 * 1637 * \param ctx GL context. 1638 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1639 * \param target texture target given by the user. 1640 * \param level image level given by the user. 1641 * \param internalFormat internal format given by the user. 1642 * \param format pixel data format given by the user. 1643 * \param type pixel data type given by the user. 1644 * \param width image width given by the user. 1645 * \param height image height given by the user. 1646 * \param depth image depth given by the user. 1647 * \param border image border given by the user. 1648 * 1649 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 1650 * 1651 * Verifies each of the parameters against the constants specified in 1652 * __struct gl_contextRec::Const and the supported extensions, and according 1653 * to the OpenGL specification. 1654 */ 1655static GLboolean 1656texture_error_check( struct gl_context *ctx, 1657 GLuint dimensions, GLenum target, 1658 GLint level, GLint internalFormat, 1659 GLenum format, GLenum type, 1660 GLint width, GLint height, 1661 GLint depth, GLint border ) 1662{ 1663 const GLenum proxyTarget = get_proxy_target(target); 1664 const GLboolean isProxy = target == proxyTarget; 1665 GLboolean sizeOK = GL_TRUE; 1666 GLboolean colorFormat; 1667 GLenum err; 1668 1669 /* Even though there are no color-index textures, we still have to support 1670 * uploading color-index data and remapping it to RGB via the 1671 * GL_PIXEL_MAP_I_TO_[RGBA] tables. 1672 */ 1673 const GLboolean indexFormat = (format == GL_COLOR_INDEX); 1674 1675 /* Note: for proxy textures, some error conditions immediately generate 1676 * a GL error in the usual way. But others do not generate a GL error. 1677 * Instead, they cause the width, height, depth, format fields of the 1678 * texture image to be zeroed-out. The GL spec seems to indicate that the 1679 * zero-out behaviour is only used in cases related to memory allocation. 1680 */ 1681 1682 /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */ 1683 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 1684 _mesa_error(ctx, GL_INVALID_VALUE, 1685 "glTexImage%dD(level=%d)", dimensions, level); 1686 return GL_TRUE; 1687 } 1688 1689 /* Check border */ 1690 if (border < 0 || border > 1 || 1691 ((ctx->API != API_OPENGL || 1692 target == GL_TEXTURE_RECTANGLE_NV || 1693 target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { 1694 _mesa_error(ctx, GL_INVALID_VALUE, 1695 "glTexImage%dD(border=%d)", dimensions, border); 1696 return GL_TRUE; 1697 } 1698 1699 if (width < 0 || height < 0 || depth < 0) { 1700 _mesa_error(ctx, GL_INVALID_VALUE, 1701 "glTexImage%dD(width, height or depth < 0)", dimensions); 1702 return GL_TRUE; 1703 } 1704 1705 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the 1706 * combinations of format, internalFormat, and type that can be used. 1707 * Formats and types that require additional extensions (e.g., GL_FLOAT 1708 * requires GL_OES_texture_float) are filtered elsewhere. 1709 */ 1710 if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) { 1711 if (format != internalFormat) { 1712 _mesa_error(ctx, GL_INVALID_OPERATION, 1713 "glTexImage%dD(format = %s, internalFormat = %s)", 1714 dimensions, 1715 _mesa_lookup_enum_by_nr(format), 1716 _mesa_lookup_enum_by_nr(internalFormat)); 1717 return GL_TRUE; 1718 } 1719 1720 err = _mesa_es_error_check_format_and_type(format, type, dimensions); 1721 if (err != GL_NO_ERROR) { 1722 _mesa_error(ctx, err, 1723 "glTexImage%dD(format = %s, type = %s)", 1724 dimensions, 1725 _mesa_lookup_enum_by_nr(format), 1726 _mesa_lookup_enum_by_nr(type)); 1727 return GL_TRUE; 1728 } 1729 } 1730 1731 /* Do this simple check before calling the TestProxyTexImage() function */ 1732 if (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { 1733 sizeOK = (width == height); 1734 } 1735 1736 /* 1737 * Use the proxy texture driver hook to see if the size/level/etc are 1738 * legal. 1739 */ 1740 sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level, 1741 internalFormat, format, 1742 type, width, height, 1743 depth, border); 1744 if (!sizeOK) { 1745 if (!isProxy) { 1746 _mesa_error(ctx, GL_INVALID_VALUE, 1747 "glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)", 1748 dimensions, level, width, height, depth); 1749 } 1750 return GL_TRUE; 1751 } 1752 1753 /* Check internalFormat */ 1754 if (_mesa_base_tex_format(ctx, internalFormat) < 0) { 1755 _mesa_error(ctx, GL_INVALID_VALUE, 1756 "glTexImage%dD(internalFormat=%s)", 1757 dimensions, _mesa_lookup_enum_by_nr(internalFormat)); 1758 return GL_TRUE; 1759 } 1760 1761 /* Check incoming image format and type */ 1762 err = _mesa_error_check_format_and_type(ctx, format, type); 1763 if (err != GL_NO_ERROR) { 1764 _mesa_error(ctx, err, 1765 "glTexImage%dD(incompatible format 0x%x, type 0x%x)", 1766 dimensions, format, type); 1767 return GL_TRUE; 1768 } 1769 1770 /* make sure internal format and format basically agree */ 1771 colorFormat = _mesa_is_color_format(format); 1772 if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) || 1773 (_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) || 1774 (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) || 1775 (_mesa_is_depthstencil_format(internalFormat) != _mesa_is_depthstencil_format(format)) || 1776 (_mesa_is_dudv_format(internalFormat) != _mesa_is_dudv_format(format))) { 1777 _mesa_error(ctx, GL_INVALID_OPERATION, 1778 "glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)", 1779 dimensions, internalFormat, format); 1780 return GL_TRUE; 1781 } 1782 1783 /* additional checks for ycbcr textures */ 1784 if (internalFormat == GL_YCBCR_MESA) { 1785 ASSERT(ctx->Extensions.MESA_ycbcr_texture); 1786 if (type != GL_UNSIGNED_SHORT_8_8_MESA && 1787 type != GL_UNSIGNED_SHORT_8_8_REV_MESA) { 1788 char message[100]; 1789 _mesa_snprintf(message, sizeof(message), 1790 "glTexImage%dD(format/type YCBCR mismatch)", 1791 dimensions); 1792 _mesa_error(ctx, GL_INVALID_ENUM, "%s", message); 1793 return GL_TRUE; /* error */ 1794 } 1795 if (target != GL_TEXTURE_2D && 1796 target != GL_PROXY_TEXTURE_2D && 1797 target != GL_TEXTURE_RECTANGLE_NV && 1798 target != GL_PROXY_TEXTURE_RECTANGLE_NV) { 1799 _mesa_error(ctx, GL_INVALID_ENUM, 1800 "glTexImage%dD(bad target for YCbCr texture)", 1801 dimensions); 1802 return GL_TRUE; 1803 } 1804 if (border != 0) { 1805 char message[100]; 1806 _mesa_snprintf(message, sizeof(message), 1807 "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)", 1808 dimensions, border); 1809 _mesa_error(ctx, GL_INVALID_VALUE, "%s", message); 1810 return GL_TRUE; 1811 } 1812 } 1813 1814 /* additional checks for depth textures */ 1815 if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) { 1816 /* Only 1D, 2D, rect, array and cube textures supported, not 3D 1817 * Cubemaps are only supported for GL version > 3.0 or with EXT_gpu_shader4 */ 1818 if (target != GL_TEXTURE_1D && 1819 target != GL_PROXY_TEXTURE_1D && 1820 target != GL_TEXTURE_2D && 1821 target != GL_PROXY_TEXTURE_2D && 1822 target != GL_TEXTURE_1D_ARRAY && 1823 target != GL_PROXY_TEXTURE_1D_ARRAY && 1824 target != GL_TEXTURE_2D_ARRAY && 1825 target != GL_PROXY_TEXTURE_2D_ARRAY && 1826 target != GL_TEXTURE_RECTANGLE_ARB && 1827 target != GL_PROXY_TEXTURE_RECTANGLE_ARB && 1828 !((_mesa_is_cube_face(target) || target == GL_PROXY_TEXTURE_CUBE_MAP) && 1829 (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))) { 1830 _mesa_error(ctx, GL_INVALID_ENUM, 1831 "glTexImage%dD(bad target for depth texture)", 1832 dimensions); 1833 return GL_TRUE; 1834 } 1835 } 1836 1837 /* additional checks for compressed textures */ 1838 if (_mesa_is_compressed_format(ctx, internalFormat)) { 1839 if (!target_can_be_compressed(ctx, target, internalFormat)) { 1840 _mesa_error(ctx, GL_INVALID_ENUM, 1841 "glTexImage%dD(target can't be compressed)", dimensions); 1842 return GL_TRUE; 1843 } 1844 if (compressedteximage_only_format(ctx, internalFormat)) { 1845 _mesa_error(ctx, GL_INVALID_OPERATION, 1846 "glTexImage%dD(no compression for format)", dimensions); 1847 return GL_TRUE; 1848 } 1849 if (border != 0) { 1850 _mesa_error(ctx, GL_INVALID_OPERATION, 1851 "glTexImage%dD(border!=0)", dimensions); 1852 return GL_TRUE; 1853 } 1854 } 1855 1856 /* additional checks for integer textures */ 1857 if ((ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) && 1858 (_mesa_is_enum_format_integer(format) != 1859 _mesa_is_enum_format_integer(internalFormat))) { 1860 _mesa_error(ctx, GL_INVALID_OPERATION, 1861 "glTexImage%dD(integer/non-integer format mismatch)", 1862 dimensions); 1863 return GL_TRUE; 1864 } 1865 1866 if (!mutable_tex_object(ctx, target)) { 1867 _mesa_error(ctx, GL_INVALID_OPERATION, 1868 "glTexImage%dD(immutable texture)", dimensions); 1869 return GL_TRUE; 1870 } 1871 1872 /* if we get here, the parameters are OK */ 1873 return GL_FALSE; 1874} 1875 1876 1877/** 1878 * Test glTexSubImage[123]D() parameters for errors. 1879 * 1880 * \param ctx GL context. 1881 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1882 * \param target texture target given by the user. 1883 * \param level image level given by the user. 1884 * \param xoffset sub-image x offset given by the user. 1885 * \param yoffset sub-image y offset given by the user. 1886 * \param zoffset sub-image z offset given by the user. 1887 * \param format pixel data format given by the user. 1888 * \param type pixel data type given by the user. 1889 * \param width image width given by the user. 1890 * \param height image height given by the user. 1891 * \param depth image depth given by the user. 1892 * 1893 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 1894 * 1895 * Verifies each of the parameters against the constants specified in 1896 * __struct gl_contextRec::Const and the supported extensions, and according 1897 * to the OpenGL specification. 1898 */ 1899static GLboolean 1900subtexture_error_check( struct gl_context *ctx, GLuint dimensions, 1901 GLenum target, GLint level, 1902 GLint xoffset, GLint yoffset, GLint zoffset, 1903 GLint width, GLint height, GLint depth, 1904 GLenum format, GLenum type ) 1905{ 1906 GLenum err; 1907 1908 /* Basic level check */ 1909 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 1910 _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level); 1911 return GL_TRUE; 1912 } 1913 1914 /* Check for negative sizes */ 1915 if (width < 0) { 1916 _mesa_error(ctx, GL_INVALID_VALUE, 1917 "glTexSubImage%dD(width=%d)", dimensions, width); 1918 return GL_TRUE; 1919 } 1920 if (height < 0 && dimensions > 1) { 1921 _mesa_error(ctx, GL_INVALID_VALUE, 1922 "glTexSubImage%dD(height=%d)", dimensions, height); 1923 return GL_TRUE; 1924 } 1925 if (depth < 0 && dimensions > 2) { 1926 _mesa_error(ctx, GL_INVALID_VALUE, 1927 "glTexSubImage%dD(depth=%d)", dimensions, depth); 1928 return GL_TRUE; 1929 } 1930 1931 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the 1932 * combinations of format and type that can be used. Formats and types 1933 * that require additional extensions (e.g., GL_FLOAT requires 1934 * GL_OES_texture_float) are filtered elsewhere. 1935 */ 1936 if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) { 1937 err = _mesa_es_error_check_format_and_type(format, type, dimensions); 1938 if (err != GL_NO_ERROR) { 1939 _mesa_error(ctx, err, 1940 "glTexSubImage%dD(format = %s, type = %s)", 1941 dimensions, 1942 _mesa_lookup_enum_by_nr(format), 1943 _mesa_lookup_enum_by_nr(type)); 1944 return GL_TRUE; 1945 } 1946 } 1947 1948 err = _mesa_error_check_format_and_type(ctx, format, type); 1949 if (err != GL_NO_ERROR) { 1950 _mesa_error(ctx, err, 1951 "glTexSubImage%dD(incompatible format 0x%x, type 0x%x)", 1952 dimensions, format, type); 1953 return GL_TRUE; 1954 } 1955 1956 return GL_FALSE; 1957} 1958 1959 1960/** 1961 * Do second part of glTexSubImage which depends on the destination texture. 1962 * \return GL_TRUE if error recorded, GL_FALSE otherwise 1963 */ 1964static GLboolean 1965subtexture_error_check2( struct gl_context *ctx, GLuint dimensions, 1966 GLenum target, GLint level, 1967 GLint xoffset, GLint yoffset, GLint zoffset, 1968 GLint width, GLint height, GLint depth, 1969 GLenum format, GLenum type, 1970 const struct gl_texture_image *destTex ) 1971{ 1972 if (!destTex) { 1973 /* undefined image level */ 1974 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions); 1975 return GL_TRUE; 1976 } 1977 1978 if (xoffset < -((GLint)destTex->Border)) { 1979 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)", 1980 dimensions); 1981 return GL_TRUE; 1982 } 1983 if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) { 1984 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)", 1985 dimensions); 1986 return GL_TRUE; 1987 } 1988 if (dimensions > 1) { 1989 GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : destTex->Border; 1990 if (yoffset < -yBorder) { 1991 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)", 1992 dimensions); 1993 return GL_TRUE; 1994 } 1995 if (yoffset + height > (GLint) destTex->Height + yBorder) { 1996 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)", 1997 dimensions); 1998 return GL_TRUE; 1999 } 2000 } 2001 if (dimensions > 2) { 2002 GLint zBorder = (target == GL_TEXTURE_2D_ARRAY) ? 0 : destTex->Border; 2003 if (zoffset < -zBorder) { 2004 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)"); 2005 return GL_TRUE; 2006 } 2007 if (zoffset + depth > (GLint) destTex->Depth + zBorder) { 2008 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)"); 2009 return GL_TRUE; 2010 } 2011 } 2012 2013 if (_mesa_is_format_compressed(destTex->TexFormat)) { 2014 GLuint bw, bh; 2015 2016 if (compressedteximage_only_format(ctx, destTex->InternalFormat)) { 2017 _mesa_error(ctx, GL_INVALID_OPERATION, 2018 "glTexSubImage%dD(no compression for format)", dimensions); 2019 return GL_TRUE; 2020 } 2021 2022 /* do tests which depend on compression block size */ 2023 _mesa_get_format_block_size(destTex->TexFormat, &bw, &bh); 2024 2025 /* offset must be multiple of block size */ 2026 if ((xoffset % bw != 0) || (yoffset % bh != 0)) { 2027 _mesa_error(ctx, GL_INVALID_OPERATION, 2028 "glTexSubImage%dD(xoffset = %d, yoffset = %d)", 2029 dimensions, xoffset, yoffset); 2030 return GL_TRUE; 2031 } 2032 /* size must be multiple of bw by bh or equal to whole texture size */ 2033 if ((width % bw != 0) && (GLuint) width != destTex->Width) { 2034 _mesa_error(ctx, GL_INVALID_OPERATION, 2035 "glTexSubImage%dD(width = %d)", dimensions, width); 2036 return GL_TRUE; 2037 } 2038 if ((height % bh != 0) && (GLuint) height != destTex->Height) { 2039 _mesa_error(ctx, GL_INVALID_OPERATION, 2040 "glTexSubImage%dD(height = %d)", dimensions, height); 2041 return GL_TRUE; 2042 } 2043 } 2044 2045 if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) { 2046 /* both source and dest must be integer-valued, or neither */ 2047 if (_mesa_is_format_integer_color(destTex->TexFormat) != 2048 _mesa_is_enum_format_integer(format)) { 2049 _mesa_error(ctx, GL_INVALID_OPERATION, 2050 "glTexSubImage%dD(integer/non-integer format mismatch)", 2051 dimensions); 2052 return GL_TRUE; 2053 } 2054 } 2055 2056 return GL_FALSE; 2057} 2058 2059 2060/** 2061 * Test glCopyTexImage[12]D() parameters for errors. 2062 * 2063 * \param ctx GL context. 2064 * \param dimensions texture image dimensions (must be 1, 2 or 3). 2065 * \param target texture target given by the user. 2066 * \param level image level given by the user. 2067 * \param internalFormat internal format given by the user. 2068 * \param width image width given by the user. 2069 * \param height image height given by the user. 2070 * \param border texture border. 2071 * 2072 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 2073 * 2074 * Verifies each of the parameters against the constants specified in 2075 * __struct gl_contextRec::Const and the supported extensions, and according 2076 * to the OpenGL specification. 2077 */ 2078static GLboolean 2079copytexture_error_check( struct gl_context *ctx, GLuint dimensions, 2080 GLenum target, GLint level, GLint internalFormat, 2081 GLint width, GLint height, GLint border ) 2082{ 2083 const GLenum proxyTarget = get_proxy_target(target); 2084 const GLenum type = GL_FLOAT; 2085 GLboolean sizeOK; 2086 GLint baseFormat; 2087 2088 /* check target */ 2089 if (!legal_texsubimage_target(ctx, dimensions, target)) { 2090 _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)", 2091 dimensions, _mesa_lookup_enum_by_nr(target)); 2092 return GL_TRUE; 2093 } 2094 2095 /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */ 2096 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 2097 _mesa_error(ctx, GL_INVALID_VALUE, 2098 "glCopyTexImage%dD(level=%d)", dimensions, level); 2099 return GL_TRUE; 2100 } 2101 2102 /* Check that the source buffer is complete */ 2103 if (_mesa_is_user_fbo(ctx->ReadBuffer)) { 2104 if (ctx->ReadBuffer->_Status == 0) { 2105 _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); 2106 } 2107 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 2108 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 2109 "glCopyTexImage%dD(invalid readbuffer)", dimensions); 2110 return GL_TRUE; 2111 } 2112 2113 if (ctx->ReadBuffer->Visual.samples > 0) { 2114 _mesa_error(ctx, GL_INVALID_OPERATION, 2115 "glCopyTexImage%dD(multisample FBO)", 2116 dimensions); 2117 return GL_TRUE; 2118 } 2119 } 2120 2121 /* Check border */ 2122 if (border < 0 || border > 1 || 2123 ((ctx->API != API_OPENGL || 2124 target == GL_TEXTURE_RECTANGLE_NV || 2125 target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { 2126 _mesa_error(ctx, GL_INVALID_VALUE, 2127 "glCopyTexImage%dD(border=%d)", dimensions, border); 2128 return GL_TRUE; 2129 } 2130 2131 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the 2132 * internalFormat. 2133 */ 2134 if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) { 2135 switch (internalFormat) { 2136 case GL_ALPHA: 2137 case GL_RGB: 2138 case GL_RGBA: 2139 case GL_LUMINANCE: 2140 case GL_LUMINANCE_ALPHA: 2141 break; 2142 default: 2143 _mesa_error(ctx, GL_INVALID_VALUE, 2144 "glCopyTexImage%dD(internalFormat)", dimensions); 2145 return GL_TRUE; 2146 } 2147 } 2148 2149 baseFormat = _mesa_base_tex_format(ctx, internalFormat); 2150 if (baseFormat < 0) { 2151 _mesa_error(ctx, GL_INVALID_VALUE, 2152 "glCopyTexImage%dD(internalFormat)", dimensions); 2153 return GL_TRUE; 2154 } 2155 2156 if (!_mesa_source_buffer_exists(ctx, baseFormat)) { 2157 _mesa_error(ctx, GL_INVALID_OPERATION, 2158 "glCopyTexImage%dD(missing readbuffer)", dimensions); 2159 return GL_TRUE; 2160 } 2161 2162 /* From the EXT_texture_integer spec: 2163 * 2164 * "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage* 2165 * if the texture internalformat is an integer format and the read color 2166 * buffer is not an integer format, or if the internalformat is not an 2167 * integer format and the read color buffer is an integer format." 2168 */ 2169 if (_mesa_is_color_format(internalFormat)) { 2170 struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; 2171 2172 if (_mesa_is_enum_format_integer(rb->InternalFormat) != 2173 _mesa_is_enum_format_integer(internalFormat)) { 2174 _mesa_error(ctx, GL_INVALID_OPERATION, 2175 "glCopyTexImage%dD(integer vs non-integer)", dimensions); 2176 return GL_TRUE; 2177 } 2178 } 2179 2180 /* Do size, level checking */ 2181 sizeOK = (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) 2182 ? (width == height) : 1; 2183 2184 sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level, 2185 internalFormat, baseFormat, 2186 type, width, height, 2187 1, border); 2188 2189 if (!sizeOK) { 2190 if (dimensions == 1) { 2191 _mesa_error(ctx, GL_INVALID_VALUE, 2192 "glCopyTexImage1D(width=%d)", width); 2193 } 2194 else { 2195 ASSERT(dimensions == 2); 2196 _mesa_error(ctx, GL_INVALID_VALUE, 2197 "glCopyTexImage2D(width=%d, height=%d)", width, height); 2198 } 2199 return GL_TRUE; 2200 } 2201 2202 if (_mesa_is_compressed_format(ctx, internalFormat)) { 2203 if (!target_can_be_compressed(ctx, target, internalFormat)) { 2204 _mesa_error(ctx, GL_INVALID_ENUM, 2205 "glCopyTexImage%dD(target)", dimensions); 2206 return GL_TRUE; 2207 } 2208 if (compressedteximage_only_format(ctx, internalFormat)) { 2209 _mesa_error(ctx, GL_INVALID_OPERATION, 2210 "glCopyTexImage%dD(no compression for format)", dimensions); 2211 return GL_TRUE; 2212 } 2213 if (border != 0) { 2214 _mesa_error(ctx, GL_INVALID_OPERATION, 2215 "glCopyTexImage%dD(border!=0)", dimensions); 2216 return GL_TRUE; 2217 } 2218 } 2219 2220 if (!mutable_tex_object(ctx, target)) { 2221 _mesa_error(ctx, GL_INVALID_OPERATION, 2222 "glCopyTexImage%dD(immutable texture)", dimensions); 2223 return GL_TRUE; 2224 } 2225 2226 /* if we get here, the parameters are OK */ 2227 return GL_FALSE; 2228} 2229 2230 2231/** 2232 * Test glCopyTexSubImage[12]D() parameters for errors. 2233 * Note that this is the first part of error checking. 2234 * See also copytexsubimage_error_check2() below for the second part. 2235 * 2236 * \param ctx GL context. 2237 * \param dimensions texture image dimensions (must be 1, 2 or 3). 2238 * \param target texture target given by the user. 2239 * \param level image level given by the user. 2240 * 2241 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 2242 */ 2243static GLboolean 2244copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions, 2245 GLenum target, GLint level) 2246{ 2247 /* Check that the source buffer is complete */ 2248 if (_mesa_is_user_fbo(ctx->ReadBuffer)) { 2249 if (ctx->ReadBuffer->_Status == 0) { 2250 _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); 2251 } 2252 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 2253 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 2254 "glCopyTexImage%dD(invalid readbuffer)", dimensions); 2255 return GL_TRUE; 2256 } 2257 2258 if (ctx->ReadBuffer->Visual.samples > 0) { 2259 _mesa_error(ctx, GL_INVALID_OPERATION, 2260 "glCopyTexSubImage%dD(multisample FBO)", 2261 dimensions); 2262 return GL_TRUE; 2263 } 2264 } 2265 2266 /* check target (proxies not allowed) */ 2267 if (!legal_texsubimage_target(ctx, dimensions, target)) { 2268 _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%uD(target=%s)", 2269 dimensions, _mesa_lookup_enum_by_nr(target)); 2270 return GL_TRUE; 2271 } 2272 2273 /* Check level */ 2274 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 2275 _mesa_error(ctx, GL_INVALID_VALUE, 2276 "glCopyTexSubImage%dD(level=%d)", dimensions, level); 2277 return GL_TRUE; 2278 } 2279 2280 return GL_FALSE; 2281} 2282 2283 2284/** 2285 * Second part of error checking for glCopyTexSubImage[12]D(). 2286 * \param xoffset sub-image x offset given by the user. 2287 * \param yoffset sub-image y offset given by the user. 2288 * \param zoffset sub-image z offset given by the user. 2289 * \param width image width given by the user. 2290 * \param height image height given by the user. 2291 */ 2292static GLboolean 2293copytexsubimage_error_check2( struct gl_context *ctx, GLuint dimensions, 2294 GLenum target, GLint level, 2295 GLint xoffset, GLint yoffset, GLint zoffset, 2296 GLsizei width, GLsizei height, 2297 const struct gl_texture_image *teximage ) 2298{ 2299 /* check that dest tex image exists */ 2300 if (!teximage) { 2301 _mesa_error(ctx, GL_INVALID_OPERATION, 2302 "glCopyTexSubImage%dD(undefined texture level: %d)", 2303 dimensions, level); 2304 return GL_TRUE; 2305 } 2306 2307 /* Check size */ 2308 if (width < 0) { 2309 _mesa_error(ctx, GL_INVALID_VALUE, 2310 "glCopyTexSubImage%dD(width=%d)", dimensions, width); 2311 return GL_TRUE; 2312 } 2313 if (dimensions > 1 && height < 0) { 2314 _mesa_error(ctx, GL_INVALID_VALUE, 2315 "glCopyTexSubImage%dD(height=%d)", dimensions, height); 2316 return GL_TRUE; 2317 } 2318 2319 /* check x/y offsets */ 2320 if (xoffset < -((GLint)teximage->Border)) { 2321 _mesa_error(ctx, GL_INVALID_VALUE, 2322 "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset); 2323 return GL_TRUE; 2324 } 2325 if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) { 2326 _mesa_error(ctx, GL_INVALID_VALUE, 2327 "glCopyTexSubImage%dD(xoffset+width)", dimensions); 2328 return GL_TRUE; 2329 } 2330 if (dimensions > 1) { 2331 GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : teximage->Border; 2332 if (yoffset < -yBorder) { 2333 _mesa_error(ctx, GL_INVALID_VALUE, 2334 "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset); 2335 return GL_TRUE; 2336 } 2337 /* NOTE: we're adding the border here, not subtracting! */ 2338 if (yoffset + height > (GLint) teximage->Height + yBorder) { 2339 _mesa_error(ctx, GL_INVALID_VALUE, 2340 "glCopyTexSubImage%dD(yoffset+height)", dimensions); 2341 return GL_TRUE; 2342 } 2343 } 2344 2345 /* check z offset */ 2346 if (dimensions > 2) { 2347 GLint zBorder = (target == GL_TEXTURE_2D_ARRAY) ? 0 : teximage->Border; 2348 if (zoffset < -zBorder) { 2349 _mesa_error(ctx, GL_INVALID_VALUE, 2350 "glCopyTexSubImage%dD(zoffset)", dimensions); 2351 return GL_TRUE; 2352 } 2353 if (zoffset > (GLint) teximage->Depth + zBorder) { 2354 _mesa_error(ctx, GL_INVALID_VALUE, 2355 "glCopyTexSubImage%dD(zoffset+depth)", dimensions); 2356 return GL_TRUE; 2357 } 2358 } 2359 2360 if (_mesa_is_format_compressed(teximage->TexFormat)) { 2361 if (compressedteximage_only_format(ctx, teximage->InternalFormat)) { 2362 _mesa_error(ctx, GL_INVALID_OPERATION, 2363 "glCopyTexSubImage%dD(no compression for format)", dimensions); 2364 return GL_TRUE; 2365 } 2366 /* offset must be multiple of 4 */ 2367 if ((xoffset & 3) || (yoffset & 3)) { 2368 _mesa_error(ctx, GL_INVALID_VALUE, 2369 "glCopyTexSubImage%dD(xoffset or yoffset)", dimensions); 2370 return GL_TRUE; 2371 } 2372 /* size must be multiple of 4 */ 2373 if ((width & 3) != 0 && (GLuint) width != teximage->Width) { 2374 _mesa_error(ctx, GL_INVALID_VALUE, 2375 "glCopyTexSubImage%dD(width)", dimensions); 2376 return GL_TRUE; 2377 } 2378 if ((height & 3) != 0 && (GLuint) height != teximage->Height) { 2379 _mesa_error(ctx, GL_INVALID_VALUE, 2380 "glCopyTexSubImage%dD(height)", dimensions); 2381 return GL_TRUE; 2382 } 2383 } 2384 2385 if (teximage->InternalFormat == GL_YCBCR_MESA) { 2386 _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D"); 2387 return GL_TRUE; 2388 } 2389 2390 if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) { 2391 _mesa_error(ctx, GL_INVALID_OPERATION, 2392 "glCopyTexSubImage%dD(missing readbuffer, format=0x%x)", 2393 dimensions, teximage->_BaseFormat); 2394 return GL_TRUE; 2395 } 2396 2397 /* From the EXT_texture_integer spec: 2398 * 2399 * "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage* 2400 * if the texture internalformat is an integer format and the read color 2401 * buffer is not an integer format, or if the internalformat is not an 2402 * integer format and the read color buffer is an integer format." 2403 */ 2404 if (_mesa_is_color_format(teximage->InternalFormat)) { 2405 struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; 2406 2407 if (_mesa_is_format_integer_color(rb->Format) != 2408 _mesa_is_format_integer_color(teximage->TexFormat)) { 2409 _mesa_error(ctx, GL_INVALID_OPERATION, 2410 "glCopyTexImage%dD(integer vs non-integer)", dimensions); 2411 return GL_TRUE; 2412 } 2413 } 2414 2415 /* if we get here, the parameters are OK */ 2416 return GL_FALSE; 2417} 2418 2419 2420/** Callback info for walking over FBO hash table */ 2421struct cb_info 2422{ 2423 struct gl_context *ctx; 2424 struct gl_texture_object *texObj; 2425 GLuint level, face; 2426}; 2427 2428 2429/** 2430 * Check render to texture callback. Called from _mesa_HashWalk(). 2431 */ 2432static void 2433check_rtt_cb(GLuint key, void *data, void *userData) 2434{ 2435 struct gl_framebuffer *fb = (struct gl_framebuffer *) data; 2436 const struct cb_info *info = (struct cb_info *) userData; 2437 struct gl_context *ctx = info->ctx; 2438 const struct gl_texture_object *texObj = info->texObj; 2439 const GLuint level = info->level, face = info->face; 2440 2441 /* If this is a user-created FBO */ 2442 if (_mesa_is_user_fbo(fb)) { 2443 GLuint i; 2444 /* check if any of the FBO's attachments point to 'texObj' */ 2445 for (i = 0; i < BUFFER_COUNT; i++) { 2446 struct gl_renderbuffer_attachment *att = fb->Attachment + i; 2447 if (att->Type == GL_TEXTURE && 2448 att->Texture == texObj && 2449 att->TextureLevel == level && 2450 att->CubeMapFace == face) { 2451 ASSERT(_mesa_get_attachment_teximage(att)); 2452 /* Tell driver about the new renderbuffer texture */ 2453 ctx->Driver.RenderTexture(ctx, ctx->DrawBuffer, att); 2454 /* Mark fb status as indeterminate to force re-validation */ 2455 fb->_Status = 0; 2456 } 2457 } 2458 } 2459} 2460 2461 2462/** 2463 * When a texture image is specified we have to check if it's bound to 2464 * any framebuffer objects (render to texture) in order to detect changes 2465 * in size or format since that effects FBO completeness. 2466 * Any FBOs rendering into the texture must be re-validated. 2467 */ 2468void 2469_mesa_update_fbo_texture(struct gl_context *ctx, 2470 struct gl_texture_object *texObj, 2471 GLuint face, GLuint level) 2472{ 2473 /* Only check this texture if it's been marked as RenderToTexture */ 2474 if (texObj->_RenderToTexture) { 2475 struct cb_info info; 2476 info.ctx = ctx; 2477 info.texObj = texObj; 2478 info.level = level; 2479 info.face = face; 2480 _mesa_HashWalk(ctx->Shared->FrameBuffers, check_rtt_cb, &info); 2481 } 2482} 2483 2484 2485/** 2486 * If the texture object's GenerateMipmap flag is set and we've 2487 * changed the texture base level image, regenerate the rest of the 2488 * mipmap levels now. 2489 */ 2490static inline void 2491check_gen_mipmap(struct gl_context *ctx, GLenum target, 2492 struct gl_texture_object *texObj, GLint level) 2493{ 2494 ASSERT(target != GL_TEXTURE_CUBE_MAP); 2495 if (texObj->GenerateMipmap && 2496 level == texObj->BaseLevel && 2497 level < texObj->MaxLevel) { 2498 ASSERT(ctx->Driver.GenerateMipmap); 2499 ctx->Driver.GenerateMipmap(ctx, target, texObj); 2500 } 2501} 2502 2503 2504/** Debug helper: override the user-requested internal format */ 2505static GLenum 2506override_internal_format(GLenum internalFormat, GLint width, GLint height) 2507{ 2508#if 0 2509 if (internalFormat == GL_RGBA16F_ARB || 2510 internalFormat == GL_RGBA32F_ARB) { 2511 printf("Convert rgba float tex to int %d x %d\n", width, height); 2512 return GL_RGBA; 2513 } 2514 else if (internalFormat == GL_RGB16F_ARB || 2515 internalFormat == GL_RGB32F_ARB) { 2516 printf("Convert rgb float tex to int %d x %d\n", width, height); 2517 return GL_RGB; 2518 } 2519 else if (internalFormat == GL_LUMINANCE_ALPHA16F_ARB || 2520 internalFormat == GL_LUMINANCE_ALPHA32F_ARB) { 2521 printf("Convert luminance float tex to int %d x %d\n", width, height); 2522 return GL_LUMINANCE_ALPHA; 2523 } 2524 else if (internalFormat == GL_LUMINANCE16F_ARB || 2525 internalFormat == GL_LUMINANCE32F_ARB) { 2526 printf("Convert luminance float tex to int %d x %d\n", width, height); 2527 return GL_LUMINANCE; 2528 } 2529 else if (internalFormat == GL_ALPHA16F_ARB || 2530 internalFormat == GL_ALPHA32F_ARB) { 2531 printf("Convert luminance float tex to int %d x %d\n", width, height); 2532 return GL_ALPHA; 2533 } 2534 /* 2535 else if (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) { 2536 internalFormat = GL_RGBA; 2537 } 2538 */ 2539 else { 2540 return internalFormat; 2541 } 2542#else 2543 return internalFormat; 2544#endif 2545} 2546 2547 2548/** 2549 * Choose the actual hardware format for a texture image. 2550 * Try to use the same format as the previous image level when possible. 2551 * Otherwise, ask the driver for the best format. 2552 * It's important to try to choose a consistant format for all levels 2553 * for efficient texture memory layout/allocation. In particular, this 2554 * comes up during automatic mipmap generation. 2555 */ 2556gl_format 2557_mesa_choose_texture_format(struct gl_context *ctx, 2558 struct gl_texture_object *texObj, 2559 GLenum target, GLint level, 2560 GLenum internalFormat, GLenum format, GLenum type) 2561{ 2562 gl_format f; 2563 2564 /* see if we've already chosen a format for the previous level */ 2565 if (level > 0) { 2566 struct gl_texture_image *prevImage = 2567 _mesa_select_tex_image(ctx, texObj, target, level - 1); 2568 /* See if the prev level is defined and has an internal format which 2569 * matches the new internal format. 2570 */ 2571 if (prevImage && 2572 prevImage->Width > 0 && 2573 prevImage->InternalFormat == internalFormat) { 2574 /* use the same format */ 2575 ASSERT(prevImage->TexFormat != MESA_FORMAT_NONE); 2576 return prevImage->TexFormat; 2577 } 2578 } 2579 2580 /* choose format from scratch */ 2581 f = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type); 2582 ASSERT(f != MESA_FORMAT_NONE); 2583 return f; 2584} 2585 2586/** 2587 * Adjust pixel unpack params and image dimensions to strip off the 2588 * one-pixel texture border. 2589 * 2590 * Gallium and intel don't support texture borders. They've seldem been used 2591 * and seldom been implemented correctly anyway. 2592 * 2593 * \param unpackNew returns the new pixel unpack parameters 2594 */ 2595static void 2596strip_texture_border(GLenum target, 2597 GLint *width, GLint *height, GLint *depth, 2598 const struct gl_pixelstore_attrib *unpack, 2599 struct gl_pixelstore_attrib *unpackNew) 2600{ 2601 assert(width); 2602 assert(height); 2603 assert(depth); 2604 2605 *unpackNew = *unpack; 2606 2607 if (unpackNew->RowLength == 0) 2608 unpackNew->RowLength = *width; 2609 2610 if (unpackNew->ImageHeight == 0) 2611 unpackNew->ImageHeight = *height; 2612 2613 assert(*width >= 3); 2614 unpackNew->SkipPixels++; /* skip the border */ 2615 *width = *width - 2; /* reduce the width by two border pixels */ 2616 2617 /* The min height of a texture with a border is 3 */ 2618 if (*height >= 3 && target != GL_TEXTURE_1D_ARRAY) { 2619 unpackNew->SkipRows++; /* skip the border */ 2620 *height = *height - 2; /* reduce the height by two border pixels */ 2621 } 2622 2623 if (*depth >= 3 && target != GL_TEXTURE_2D_ARRAY) { 2624 unpackNew->SkipImages++; /* skip the border */ 2625 *depth = *depth - 2; /* reduce the depth by two border pixels */ 2626 } 2627} 2628 2629/** 2630 * Common code to implement all the glTexImage1D/2D/3D functions. 2631 */ 2632static void 2633teximage(struct gl_context *ctx, GLuint dims, 2634 GLenum target, GLint level, GLint internalFormat, 2635 GLsizei width, GLsizei height, GLsizei depth, 2636 GLint border, GLenum format, GLenum type, 2637 const GLvoid *pixels) 2638{ 2639 GLboolean error; 2640 struct gl_pixelstore_attrib unpack_no_border; 2641 const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; 2642 2643 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2644 2645 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2646 _mesa_debug(ctx, "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n", 2647 dims, 2648 _mesa_lookup_enum_by_nr(target), level, 2649 _mesa_lookup_enum_by_nr(internalFormat), 2650 width, height, depth, border, 2651 _mesa_lookup_enum_by_nr(format), 2652 _mesa_lookup_enum_by_nr(type), pixels); 2653 2654 internalFormat = override_internal_format(internalFormat, width, height); 2655 2656 /* target error checking */ 2657 if (!legal_teximage_target(ctx, dims, target)) { 2658 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%uD(target=%s)", 2659 dims, _mesa_lookup_enum_by_nr(target)); 2660 return; 2661 } 2662 2663 /* general error checking */ 2664 error = texture_error_check(ctx, dims, target, level, internalFormat, 2665 format, type, width, height, depth, border); 2666 2667 if (_mesa_is_proxy_texture(target)) { 2668 /* Proxy texture: just clear or set state depending on error checking */ 2669 struct gl_texture_image *texImage = 2670 _mesa_get_proxy_tex_image(ctx, target, level); 2671 2672 if (error) { 2673 /* when error, clear all proxy texture image parameters */ 2674 if (texImage) 2675 clear_teximage_fields(texImage); 2676 } 2677 else { 2678 /* no error, set the tex image parameters */ 2679 struct gl_texture_object *texObj = 2680 _mesa_get_current_tex_object(ctx, target); 2681 gl_format texFormat = _mesa_choose_texture_format(ctx, texObj, 2682 target, level, 2683 internalFormat, 2684 format, type); 2685 2686 if (legal_texture_size(ctx, texFormat, width, height, depth)) { 2687 _mesa_init_teximage_fields(ctx, texImage, width, height, 2688 depth, border, internalFormat, 2689 texFormat); 2690 } 2691 else if (texImage) { 2692 clear_teximage_fields(texImage); 2693 } 2694 } 2695 } 2696 else { 2697 /* non-proxy target */ 2698 const GLuint face = _mesa_tex_target_to_face(target); 2699 struct gl_texture_object *texObj; 2700 struct gl_texture_image *texImage; 2701 2702 if (error) { 2703 return; /* error was recorded */ 2704 } 2705 2706 /* Allow a hardware driver to just strip out the border, to provide 2707 * reliable but slightly incorrect hardware rendering instead of 2708 * rarely-tested software fallback rendering. 2709 */ 2710 if (border && ctx->Const.StripTextureBorder) { 2711 strip_texture_border(target, &width, &height, &depth, unpack, 2712 &unpack_no_border); 2713 border = 0; 2714 unpack = &unpack_no_border; 2715 } 2716 2717 if (ctx->NewState & _NEW_PIXEL) 2718 _mesa_update_state(ctx); 2719 2720 texObj = _mesa_get_current_tex_object(ctx, target); 2721 2722 _mesa_lock_texture(ctx, texObj); 2723 { 2724 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 2725 2726 if (!texImage) { 2727 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims); 2728 } 2729 else { 2730 gl_format texFormat; 2731 2732 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 2733 2734 texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, 2735 internalFormat, format, 2736 type); 2737 2738 if (legal_texture_size(ctx, texFormat, width, height, depth)) { 2739 _mesa_init_teximage_fields(ctx, texImage, 2740 width, height, depth, 2741 border, internalFormat, texFormat); 2742 2743 /* Give the texture to the driver. <pixels> may be null. */ 2744 ctx->Driver.TexImage(ctx, dims, texImage, format, 2745 type, pixels, unpack); 2746 2747 check_gen_mipmap(ctx, target, texObj, level); 2748 2749 _mesa_update_fbo_texture(ctx, texObj, face, level); 2750 2751 _mesa_dirty_texobj(ctx, texObj, GL_TRUE); 2752 } 2753 else { 2754 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims); 2755 } 2756 } 2757 } 2758 _mesa_unlock_texture(ctx, texObj); 2759 } 2760} 2761 2762 2763/* 2764 * Called from the API. Note that width includes the border. 2765 */ 2766void GLAPIENTRY 2767_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, 2768 GLsizei width, GLint border, GLenum format, 2769 GLenum type, const GLvoid *pixels ) 2770{ 2771 GET_CURRENT_CONTEXT(ctx); 2772 teximage(ctx, 1, target, level, internalFormat, width, 1, 1, 2773 border, format, type, pixels); 2774} 2775 2776 2777void GLAPIENTRY 2778_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, 2779 GLsizei width, GLsizei height, GLint border, 2780 GLenum format, GLenum type, 2781 const GLvoid *pixels ) 2782{ 2783 GET_CURRENT_CONTEXT(ctx); 2784 teximage(ctx, 2, target, level, internalFormat, width, height, 1, 2785 border, format, type, pixels); 2786} 2787 2788 2789/* 2790 * Called by the API or display list executor. 2791 * Note that width and height include the border. 2792 */ 2793void GLAPIENTRY 2794_mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, 2795 GLsizei width, GLsizei height, GLsizei depth, 2796 GLint border, GLenum format, GLenum type, 2797 const GLvoid *pixels ) 2798{ 2799 GET_CURRENT_CONTEXT(ctx); 2800 teximage(ctx, 3, target, level, internalFormat, width, height, depth, 2801 border, format, type, pixels); 2802} 2803 2804 2805void GLAPIENTRY 2806_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat, 2807 GLsizei width, GLsizei height, GLsizei depth, 2808 GLint border, GLenum format, GLenum type, 2809 const GLvoid *pixels ) 2810{ 2811 _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height, 2812 depth, border, format, type, pixels); 2813} 2814 2815 2816#if FEATURE_OES_EGL_image 2817void GLAPIENTRY 2818_mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) 2819{ 2820 struct gl_texture_object *texObj; 2821 struct gl_texture_image *texImage; 2822 bool valid_target; 2823 GET_CURRENT_CONTEXT(ctx); 2824 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2825 2826 switch (target) { 2827 case GL_TEXTURE_2D: 2828 valid_target = ctx->Extensions.OES_EGL_image; 2829 break; 2830 case GL_TEXTURE_EXTERNAL_OES: 2831 valid_target = ctx->Extensions.OES_EGL_image_external; 2832 break; 2833 default: 2834 valid_target = false; 2835 break; 2836 } 2837 2838 if (!valid_target) { 2839 _mesa_error(ctx, GL_INVALID_ENUM, 2840 "glEGLImageTargetTexture2D(target=%d)", target); 2841 return; 2842 } 2843 2844 if (ctx->NewState & _NEW_PIXEL) 2845 _mesa_update_state(ctx); 2846 2847 texObj = _mesa_get_current_tex_object(ctx, target); 2848 _mesa_lock_texture(ctx, texObj); 2849 2850 if (texObj->Immutable) { 2851 _mesa_error(ctx, GL_INVALID_OPERATION, 2852 "glEGLImageTargetTexture2D(texture is immutable)"); 2853 _mesa_unlock_texture(ctx, texObj); 2854 return; 2855 } 2856 2857 texImage = _mesa_get_tex_image(ctx, texObj, target, 0); 2858 if (!texImage) { 2859 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEGLImageTargetTexture2D"); 2860 } else { 2861 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 2862 2863 ctx->Driver.EGLImageTargetTexture2D(ctx, target, 2864 texObj, texImage, image); 2865 2866 _mesa_dirty_texobj(ctx, texObj, GL_TRUE); 2867 } 2868 _mesa_unlock_texture(ctx, texObj); 2869 2870} 2871#endif 2872 2873 2874 2875/** 2876 * Implement all the glTexSubImage1/2/3D() functions. 2877 */ 2878static void 2879texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, 2880 GLint xoffset, GLint yoffset, GLint zoffset, 2881 GLsizei width, GLsizei height, GLsizei depth, 2882 GLenum format, GLenum type, const GLvoid *pixels ) 2883{ 2884 struct gl_texture_object *texObj; 2885 struct gl_texture_image *texImage; 2886 2887 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2888 2889 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2890 _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n", 2891 dims, 2892 _mesa_lookup_enum_by_nr(target), level, 2893 xoffset, yoffset, zoffset, width, height, depth, 2894 _mesa_lookup_enum_by_nr(format), 2895 _mesa_lookup_enum_by_nr(type), pixels); 2896 2897 /* check target (proxies not allowed) */ 2898 if (!legal_texsubimage_target(ctx, dims, target)) { 2899 _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)", 2900 dims, _mesa_lookup_enum_by_nr(target)); 2901 return; 2902 } 2903 2904 if (ctx->NewState & _NEW_PIXEL) 2905 _mesa_update_state(ctx); 2906 2907 if (subtexture_error_check(ctx, dims, target, level, xoffset, yoffset, zoffset, 2908 width, height, depth, format, type)) { 2909 return; /* error was detected */ 2910 } 2911 2912 texObj = _mesa_get_current_tex_object(ctx, target); 2913 2914 _mesa_lock_texture(ctx, texObj); 2915 { 2916 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 2917 2918 if (subtexture_error_check2(ctx, dims, target, level, 2919 xoffset, yoffset, zoffset, 2920 width, height, depth, 2921 format, type, texImage)) { 2922 /* error was recorded */ 2923 } 2924 else if (width > 0 && height > 0 && depth > 0) { 2925 /* If we have a border, offset=-1 is legal. Bias by border width. */ 2926 switch (dims) { 2927 case 3: 2928 if (target != GL_TEXTURE_2D_ARRAY) 2929 zoffset += texImage->Border; 2930 /* fall-through */ 2931 case 2: 2932 if (target != GL_TEXTURE_1D_ARRAY) 2933 yoffset += texImage->Border; 2934 /* fall-through */ 2935 case 1: 2936 xoffset += texImage->Border; 2937 } 2938 2939 ctx->Driver.TexSubImage(ctx, dims, texImage, 2940 xoffset, yoffset, zoffset, 2941 width, height, depth, 2942 format, type, pixels, &ctx->Unpack); 2943 2944 check_gen_mipmap(ctx, target, texObj, level); 2945 2946 ctx->NewState |= _NEW_TEXTURE; 2947 } 2948 } 2949 _mesa_unlock_texture(ctx, texObj); 2950} 2951 2952 2953void GLAPIENTRY 2954_mesa_TexSubImage1D( GLenum target, GLint level, 2955 GLint xoffset, GLsizei width, 2956 GLenum format, GLenum type, 2957 const GLvoid *pixels ) 2958{ 2959 GET_CURRENT_CONTEXT(ctx); 2960 texsubimage(ctx, 1, target, level, 2961 xoffset, 0, 0, 2962 width, 1, 1, 2963 format, type, pixels); 2964} 2965 2966 2967void GLAPIENTRY 2968_mesa_TexSubImage2D( GLenum target, GLint level, 2969 GLint xoffset, GLint yoffset, 2970 GLsizei width, GLsizei height, 2971 GLenum format, GLenum type, 2972 const GLvoid *pixels ) 2973{ 2974 GET_CURRENT_CONTEXT(ctx); 2975 texsubimage(ctx, 2, target, level, 2976 xoffset, yoffset, 0, 2977 width, height, 1, 2978 format, type, pixels); 2979} 2980 2981 2982 2983void GLAPIENTRY 2984_mesa_TexSubImage3D( GLenum target, GLint level, 2985 GLint xoffset, GLint yoffset, GLint zoffset, 2986 GLsizei width, GLsizei height, GLsizei depth, 2987 GLenum format, GLenum type, 2988 const GLvoid *pixels ) 2989{ 2990 GET_CURRENT_CONTEXT(ctx); 2991 texsubimage(ctx, 3, target, level, 2992 xoffset, yoffset, zoffset, 2993 width, height, depth, 2994 format, type, pixels); 2995} 2996 2997 2998 2999/** 3000 * For glCopyTexSubImage, return the source renderbuffer to copy texel data 3001 * from. This depends on whether the texture contains color or depth values. 3002 */ 3003static struct gl_renderbuffer * 3004get_copy_tex_image_source(struct gl_context *ctx, gl_format texFormat) 3005{ 3006 if (_mesa_get_format_bits(texFormat, GL_DEPTH_BITS) > 0) { 3007 /* reading from depth/stencil buffer */ 3008 return ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; 3009 } 3010 else { 3011 /* copying from color buffer */ 3012 return ctx->ReadBuffer->_ColorReadBuffer; 3013 } 3014} 3015 3016 3017 3018/** 3019 * Implement the glCopyTexImage1/2D() functions. 3020 */ 3021static void 3022copyteximage(struct gl_context *ctx, GLuint dims, 3023 GLenum target, GLint level, GLenum internalFormat, 3024 GLint x, GLint y, GLsizei width, GLsizei height, GLint border ) 3025{ 3026 struct gl_texture_object *texObj; 3027 struct gl_texture_image *texImage; 3028 const GLuint face = _mesa_tex_target_to_face(target); 3029 3030 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3031 3032 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3033 _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n", 3034 dims, 3035 _mesa_lookup_enum_by_nr(target), level, 3036 _mesa_lookup_enum_by_nr(internalFormat), 3037 x, y, width, height, border); 3038 3039 if (ctx->NewState & NEW_COPY_TEX_STATE) 3040 _mesa_update_state(ctx); 3041 3042 if (copytexture_error_check(ctx, dims, target, level, internalFormat, 3043 width, height, border)) 3044 return; 3045 3046 texObj = _mesa_get_current_tex_object(ctx, target); 3047 3048 if (border && ctx->Const.StripTextureBorder) { 3049 x += border; 3050 width -= border * 2; 3051 if (dims == 2) { 3052 y += border; 3053 height -= border * 2; 3054 } 3055 border = 0; 3056 } 3057 3058 _mesa_lock_texture(ctx, texObj); 3059 { 3060 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 3061 3062 if (!texImage) { 3063 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims); 3064 } 3065 else { 3066 /* choose actual hw format */ 3067 gl_format texFormat = _mesa_choose_texture_format(ctx, texObj, 3068 target, level, 3069 internalFormat, 3070 GL_NONE, GL_NONE); 3071 3072 if (legal_texture_size(ctx, texFormat, width, height, 1)) { 3073 GLint srcX = x, srcY = y, dstX = 0, dstY = 0, dstZ = 0; 3074 3075 /* Free old texture image */ 3076 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 3077 3078 _mesa_init_teximage_fields(ctx, texImage, width, height, 1, 3079 border, internalFormat, texFormat); 3080 3081 /* Allocate texture memory (no pixel data yet) */ 3082 ctx->Driver.TexImage(ctx, dims, texImage, 3083 GL_NONE, GL_NONE, 3084 NULL, &ctx->Unpack); 3085 3086 if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY, 3087 &width, &height)) { 3088 struct gl_renderbuffer *srcRb = 3089 get_copy_tex_image_source(ctx, texImage->TexFormat); 3090 3091 ctx->Driver.CopyTexSubImage(ctx, dims, texImage, dstX, dstY, dstZ, 3092 srcRb, srcX, srcY, width, height); 3093 } 3094 3095 check_gen_mipmap(ctx, target, texObj, level); 3096 3097 _mesa_update_fbo_texture(ctx, texObj, face, level); 3098 3099 _mesa_dirty_texobj(ctx, texObj, GL_TRUE); 3100 } 3101 else { 3102 /* probably too large of image */ 3103 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims); 3104 } 3105 } 3106 } 3107 _mesa_unlock_texture(ctx, texObj); 3108} 3109 3110 3111 3112void GLAPIENTRY 3113_mesa_CopyTexImage1D( GLenum target, GLint level, 3114 GLenum internalFormat, 3115 GLint x, GLint y, 3116 GLsizei width, GLint border ) 3117{ 3118 GET_CURRENT_CONTEXT(ctx); 3119 copyteximage(ctx, 1, target, level, internalFormat, x, y, width, 1, border); 3120} 3121 3122 3123 3124void GLAPIENTRY 3125_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, 3126 GLint x, GLint y, GLsizei width, GLsizei height, 3127 GLint border ) 3128{ 3129 GET_CURRENT_CONTEXT(ctx); 3130 copyteximage(ctx, 2, target, level, internalFormat, 3131 x, y, width, height, border); 3132} 3133 3134 3135 3136/** 3137 * Implementation for glCopyTexSubImage1/2/3D() functions. 3138 */ 3139static void 3140copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, 3141 GLint xoffset, GLint yoffset, GLint zoffset, 3142 GLint x, GLint y, GLsizei width, GLsizei height) 3143{ 3144 struct gl_texture_object *texObj; 3145 struct gl_texture_image *texImage; 3146 3147 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3148 3149 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3150 _mesa_debug(ctx, "glCopyTexSubImage%uD %s %d %d %d %d %d %d %d %d\n", 3151 dims, 3152 _mesa_lookup_enum_by_nr(target), 3153 level, xoffset, yoffset, zoffset, x, y, width, height); 3154 3155 if (ctx->NewState & NEW_COPY_TEX_STATE) 3156 _mesa_update_state(ctx); 3157 3158 if (copytexsubimage_error_check1(ctx, dims, target, level)) 3159 return; 3160 3161 texObj = _mesa_get_current_tex_object(ctx, target); 3162 3163 _mesa_lock_texture(ctx, texObj); 3164 { 3165 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3166 3167 if (copytexsubimage_error_check2(ctx, dims, target, level, xoffset, yoffset, 3168 zoffset, width, height, texImage)) { 3169 /* error was recored */ 3170 } 3171 else { 3172 /* If we have a border, offset=-1 is legal. Bias by border width. */ 3173 switch (dims) { 3174 case 3: 3175 if (target != GL_TEXTURE_2D_ARRAY) 3176 zoffset += texImage->Border; 3177 /* fall-through */ 3178 case 2: 3179 if (target != GL_TEXTURE_1D_ARRAY) 3180 yoffset += texImage->Border; 3181 /* fall-through */ 3182 case 1: 3183 xoffset += texImage->Border; 3184 } 3185 3186 if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, 3187 &width, &height)) { 3188 struct gl_renderbuffer *srcRb = 3189 get_copy_tex_image_source(ctx, texImage->TexFormat); 3190 3191 ctx->Driver.CopyTexSubImage(ctx, dims, texImage, 3192 xoffset, yoffset, zoffset, 3193 srcRb, x, y, width, height); 3194 3195 check_gen_mipmap(ctx, target, texObj, level); 3196 3197 ctx->NewState |= _NEW_TEXTURE; 3198 } 3199 } 3200 } 3201 _mesa_unlock_texture(ctx, texObj); 3202} 3203 3204 3205void GLAPIENTRY 3206_mesa_CopyTexSubImage1D( GLenum target, GLint level, 3207 GLint xoffset, GLint x, GLint y, GLsizei width ) 3208{ 3209 GET_CURRENT_CONTEXT(ctx); 3210 copytexsubimage(ctx, 1, target, level, xoffset, 0, 0, x, y, width, 1); 3211} 3212 3213 3214 3215void GLAPIENTRY 3216_mesa_CopyTexSubImage2D( GLenum target, GLint level, 3217 GLint xoffset, GLint yoffset, 3218 GLint x, GLint y, GLsizei width, GLsizei height ) 3219{ 3220 GET_CURRENT_CONTEXT(ctx); 3221 copytexsubimage(ctx, 2, target, level, xoffset, yoffset, 0, x, y, 3222 width, height); 3223} 3224 3225 3226 3227void GLAPIENTRY 3228_mesa_CopyTexSubImage3D( GLenum target, GLint level, 3229 GLint xoffset, GLint yoffset, GLint zoffset, 3230 GLint x, GLint y, GLsizei width, GLsizei height ) 3231{ 3232 GET_CURRENT_CONTEXT(ctx); 3233 copytexsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, 3234 x, y, width, height); 3235} 3236 3237 3238 3239 3240/**********************************************************************/ 3241/****** Compressed Textures ******/ 3242/**********************************************************************/ 3243 3244 3245/** 3246 * Return expected size of a compressed texture. 3247 */ 3248static GLuint 3249compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth, 3250 GLenum glformat) 3251{ 3252 gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat); 3253 return _mesa_format_image_size(mesaFormat, width, height, depth); 3254} 3255 3256 3257/* 3258 * Return compressed texture block size, in pixels. 3259 */ 3260static void 3261get_compressed_block_size(GLenum glformat, GLuint *bw, GLuint *bh) 3262{ 3263 gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat); 3264 _mesa_get_format_block_size(mesaFormat, bw, bh); 3265} 3266 3267 3268/** 3269 * Error checking for glCompressedTexImage[123]D(). 3270 * \param reason returns reason for error, if any 3271 * \return error code or GL_NO_ERROR. 3272 */ 3273static GLenum 3274compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, 3275 GLenum target, GLint level, 3276 GLenum internalFormat, GLsizei width, 3277 GLsizei height, GLsizei depth, GLint border, 3278 GLsizei imageSize, char **reason) 3279{ 3280 const GLenum proxyTarget = get_proxy_target(target); 3281 const GLint maxLevels = _mesa_max_texture_levels(ctx, target); 3282 GLint expectedSize; 3283 GLenum choose_format; 3284 GLenum choose_type; 3285 GLenum proxy_format; 3286 3287 *reason = ""; /* no error */ 3288 3289 if (!target_can_be_compressed(ctx, target, internalFormat)) { 3290 *reason = "target"; 3291 return GL_INVALID_ENUM; 3292 } 3293 3294 /* This will detect any invalid internalFormat value */ 3295 if (!_mesa_is_compressed_format(ctx, internalFormat)) { 3296 *reason = "internalFormat"; 3297 return GL_INVALID_ENUM; 3298 } 3299 3300 switch (internalFormat) { 3301#if FEATURE_ES 3302 case GL_PALETTE4_RGB8_OES: 3303 case GL_PALETTE4_RGBA8_OES: 3304 case GL_PALETTE4_R5_G6_B5_OES: 3305 case GL_PALETTE4_RGBA4_OES: 3306 case GL_PALETTE4_RGB5_A1_OES: 3307 case GL_PALETTE8_RGB8_OES: 3308 case GL_PALETTE8_RGBA8_OES: 3309 case GL_PALETTE8_R5_G6_B5_OES: 3310 case GL_PALETTE8_RGBA4_OES: 3311 case GL_PALETTE8_RGB5_A1_OES: 3312 _mesa_cpal_compressed_format_type(internalFormat, &choose_format, 3313 &choose_type); 3314 proxy_format = choose_format; 3315 3316 /* check level */ 3317 if (level > 0 || level < -maxLevels) { 3318 *reason = "level"; 3319 return GL_INVALID_VALUE; 3320 } 3321 3322 if (dimensions != 2) { 3323 *reason = "compressed paletted textures must be 2D"; 3324 return GL_INVALID_OPERATION; 3325 } 3326 3327 /* Figure out the expected texture size (in bytes). This will be 3328 * checked against the actual size later. 3329 */ 3330 expectedSize = _mesa_cpal_compressed_size(level, internalFormat, 3331 width, height); 3332 3333 /* This is for the benefit of the TestProxyTexImage below. It expects 3334 * level to be non-negative. OES_compressed_paletted_texture uses a 3335 * weird mechanism where the level specified to glCompressedTexImage2D 3336 * is -(n-1) number of levels in the texture, and the data specifies the 3337 * complete mipmap stack. This is done to ensure the palette is the 3338 * same for all levels. 3339 */ 3340 level = -level; 3341 break; 3342#endif 3343 3344 default: 3345 choose_format = GL_NONE; 3346 choose_type = GL_NONE; 3347 proxy_format = internalFormat; 3348 3349 /* check level */ 3350 if (level < 0 || level >= maxLevels) { 3351 *reason = "level"; 3352 return GL_INVALID_VALUE; 3353 } 3354 3355 /* Figure out the expected texture size (in bytes). This will be 3356 * checked against the actual size later. 3357 */ 3358 expectedSize = compressed_tex_size(width, height, depth, internalFormat); 3359 break; 3360 } 3361 3362 /* This should really never fail */ 3363 if (_mesa_base_tex_format(ctx, internalFormat) < 0) { 3364 *reason = "internalFormat"; 3365 return GL_INVALID_ENUM; 3366 } 3367 3368 /* No compressed formats support borders at this time */ 3369 if (border != 0) { 3370 *reason = "border != 0"; 3371 return GL_INVALID_VALUE; 3372 } 3373 3374 /* For cube map, width must equal height */ 3375 if (_mesa_is_cube_face(target) && width != height) { 3376 *reason = "width != height"; 3377 return GL_INVALID_VALUE; 3378 } 3379 3380 /* check image size against compression block size */ 3381 { 3382 gl_format texFormat = 3383 ctx->Driver.ChooseTextureFormat(ctx, proxy_format, 3384 choose_format, choose_type); 3385 GLuint bw, bh; 3386 3387 _mesa_get_format_block_size(texFormat, &bw, &bh); 3388 if ((width > bw && width % bw > 0) || 3389 (height > bh && height % bh > 0)) { 3390 /* 3391 * Per GL_ARB_texture_compression: GL_INVALID_OPERATION is 3392 * generated [...] if any parameter combinations are not 3393 * supported by the specific compressed internal format. 3394 */ 3395 *reason = "invalid width or height for compression format"; 3396 return GL_INVALID_OPERATION; 3397 } 3398 } 3399 3400 /* check image sizes */ 3401 if (!ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level, 3402 proxy_format, choose_format, 3403 choose_type, 3404 width, height, depth, border)) { 3405 /* See error comment above */ 3406 *reason = "invalid width, height or format"; 3407 return GL_INVALID_OPERATION; 3408 } 3409 3410 /* check image size in bytes */ 3411 if (expectedSize != imageSize) { 3412 /* Per GL_ARB_texture_compression: GL_INVALID_VALUE is generated [...] 3413 * if <imageSize> is not consistent with the format, dimensions, and 3414 * contents of the specified image. 3415 */ 3416 *reason = "imageSize inconsistant with width/height/format"; 3417 return GL_INVALID_VALUE; 3418 } 3419 3420 if (!mutable_tex_object(ctx, target)) { 3421 *reason = "immutable texture"; 3422 return GL_INVALID_OPERATION; 3423 } 3424 3425 return GL_NO_ERROR; 3426} 3427 3428 3429/** 3430 * Error checking for glCompressedTexSubImage[123]D(). 3431 * \warning There are some bad assumptions here about the size of compressed 3432 * texture tiles (multiple of 4) used to test the validity of the 3433 * offset and size parameters. 3434 * \return error code or GL_NO_ERROR. 3435 */ 3436static GLenum 3437compressed_subtexture_error_check(struct gl_context *ctx, GLint dimensions, 3438 GLenum target, GLint level, 3439 GLint xoffset, GLint yoffset, GLint zoffset, 3440 GLsizei width, GLsizei height, GLsizei depth, 3441 GLenum format, GLsizei imageSize) 3442{ 3443 GLint expectedSize, maxLevels = 0, maxTextureSize; 3444 GLuint bw, bh; 3445 (void) zoffset; 3446 3447 if (dimensions == 1) { 3448 /* 1D compressed textures not allowed */ 3449 return GL_INVALID_ENUM; 3450 } 3451 else if (dimensions == 2) { 3452 if (target == GL_PROXY_TEXTURE_2D) { 3453 maxLevels = ctx->Const.MaxTextureLevels; 3454 } 3455 else if (target == GL_TEXTURE_2D) { 3456 maxLevels = ctx->Const.MaxTextureLevels; 3457 } 3458 else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { 3459 if (!ctx->Extensions.ARB_texture_cube_map) 3460 return GL_INVALID_ENUM; /*target*/ 3461 maxLevels = ctx->Const.MaxCubeTextureLevels; 3462 } 3463 else if (_mesa_is_cube_face(target)) { 3464 if (!ctx->Extensions.ARB_texture_cube_map) 3465 return GL_INVALID_ENUM; /*target*/ 3466 maxLevels = ctx->Const.MaxCubeTextureLevels; 3467 } 3468 else { 3469 return GL_INVALID_ENUM; /*target*/ 3470 } 3471 } 3472 else if (dimensions == 3) { 3473 /* 3D compressed textures not allowed */ 3474 return GL_INVALID_ENUM; 3475 } 3476 3477 maxTextureSize = 1 << (maxLevels - 1); 3478 3479 /* this will catch any invalid compressed format token */ 3480 if (!_mesa_is_compressed_format(ctx, format)) 3481 return GL_INVALID_ENUM; 3482 3483 if (width < 1 || width > maxTextureSize) 3484 return GL_INVALID_VALUE; 3485 3486 if ((height < 1 || height > maxTextureSize) 3487 && dimensions > 1) 3488 return GL_INVALID_VALUE; 3489 3490 if (level < 0 || level >= maxLevels) 3491 return GL_INVALID_VALUE; 3492 3493 /* 3494 * do checks which depend on compression block size 3495 */ 3496 get_compressed_block_size(format, &bw, &bh); 3497 3498 if ((xoffset % bw != 0) || (yoffset % bh != 0)) 3499 return GL_INVALID_VALUE; 3500 3501 if ((width % bw != 0) && width != 2 && width != 1) 3502 return GL_INVALID_VALUE; 3503 3504 if ((height % bh != 0) && height != 2 && height != 1) 3505 return GL_INVALID_VALUE; 3506 3507 expectedSize = compressed_tex_size(width, height, depth, format); 3508 if (expectedSize != imageSize) 3509 return GL_INVALID_VALUE; 3510 3511 return GL_NO_ERROR; 3512} 3513 3514 3515/** 3516 * Do second part of glCompressedTexSubImage error checking. 3517 * \return GL_TRUE if error found, GL_FALSE otherwise. 3518 */ 3519static GLboolean 3520compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims, 3521 GLsizei width, GLsizei height, 3522 GLsizei depth, GLenum format, 3523 struct gl_texture_image *texImage) 3524{ 3525 3526 if ((GLint) format != texImage->InternalFormat) { 3527 _mesa_error(ctx, GL_INVALID_OPERATION, 3528 "glCompressedTexSubImage%uD(format=0x%x)", dims, format); 3529 return GL_TRUE; 3530 } 3531 3532 if (compressedteximage_only_format(ctx, format)) { 3533 _mesa_error(ctx, GL_INVALID_OPERATION, 3534 "glCompressedTexSubImage%uD(format=0x%x cannot be updated)" 3535 , dims, format); 3536 return GL_TRUE; 3537 } 3538 3539 if (((width == 1 || width == 2) && 3540 width != (GLsizei) texImage->Width) || 3541 (width > (GLsizei) texImage->Width)) { 3542 _mesa_error(ctx, GL_INVALID_VALUE, 3543 "glCompressedTexSubImage%uD(width=%d)", dims, width); 3544 return GL_TRUE; 3545 } 3546 3547 if (dims >= 2) { 3548 if (((height == 1 || height == 2) && 3549 height != (GLsizei) texImage->Height) || 3550 (height > (GLsizei) texImage->Height)) { 3551 _mesa_error(ctx, GL_INVALID_VALUE, 3552 "glCompressedTexSubImage%uD(height=%d)", dims, height); 3553 return GL_TRUE; 3554 } 3555 } 3556 3557 if (dims >= 3) { 3558 if (((depth == 1 || depth == 2) && 3559 depth != (GLsizei) texImage->Depth) || 3560 (depth > (GLsizei) texImage->Depth)) { 3561 _mesa_error(ctx, GL_INVALID_VALUE, 3562 "glCompressedTexSubImage%uD(depth=%d)", dims, depth); 3563 return GL_TRUE; 3564 } 3565 } 3566 3567 return GL_FALSE; 3568} 3569 3570 3571/** 3572 * Implementation of the glCompressedTexImage1/2/3D() functions. 3573 */ 3574static void 3575compressedteximage(struct gl_context *ctx, GLuint dims, 3576 GLenum target, GLint level, 3577 GLenum internalFormat, GLsizei width, 3578 GLsizei height, GLsizei depth, GLint border, 3579 GLsizei imageSize, const GLvoid *data) 3580{ 3581 GLenum error; 3582 char *reason = ""; 3583 3584 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3585 3586 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3587 _mesa_debug(ctx, 3588 "glCompressedTexImage%uDARB %s %d %s %d %d %d %d %d %p\n", 3589 dims, 3590 _mesa_lookup_enum_by_nr(target), level, 3591 _mesa_lookup_enum_by_nr(internalFormat), 3592 width, height, depth, border, imageSize, data); 3593 3594 /* check target */ 3595 if (!legal_teximage_target(ctx, dims, target)) { 3596 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage%uD(target=%s)", 3597 dims, _mesa_lookup_enum_by_nr(target)); 3598 return; 3599 } 3600 3601 error = compressed_texture_error_check(ctx, dims, target, level, 3602 internalFormat, width, height, depth, 3603 border, imageSize, &reason); 3604 3605#if FEATURE_ES 3606 /* XXX this is kind of a hack */ 3607 if (!error && dims == 2) { 3608 switch (internalFormat) { 3609 case GL_PALETTE4_RGB8_OES: 3610 case GL_PALETTE4_RGBA8_OES: 3611 case GL_PALETTE4_R5_G6_B5_OES: 3612 case GL_PALETTE4_RGBA4_OES: 3613 case GL_PALETTE4_RGB5_A1_OES: 3614 case GL_PALETTE8_RGB8_OES: 3615 case GL_PALETTE8_RGBA8_OES: 3616 case GL_PALETTE8_R5_G6_B5_OES: 3617 case GL_PALETTE8_RGBA4_OES: 3618 case GL_PALETTE8_RGB5_A1_OES: 3619 _mesa_cpal_compressed_teximage2d(target, level, internalFormat, 3620 width, height, imageSize, data); 3621 return; 3622 } 3623 } 3624#endif 3625 3626 if (_mesa_is_proxy_texture(target)) { 3627 /* Proxy texture: just check for errors and update proxy state */ 3628 struct gl_texture_image *texImage; 3629 3630 if (!error) { 3631 struct gl_texture_object *texObj = 3632 _mesa_get_current_tex_object(ctx, target); 3633 gl_format texFormat = 3634 _mesa_choose_texture_format(ctx, texObj, target, level, 3635 internalFormat, GL_NONE, GL_NONE); 3636 if (!legal_texture_size(ctx, texFormat, width, height, depth)) { 3637 error = GL_OUT_OF_MEMORY; 3638 } 3639 } 3640 3641 texImage = _mesa_get_proxy_tex_image(ctx, target, level); 3642 if (texImage) { 3643 if (error) { 3644 /* if error, clear all proxy texture image parameters */ 3645 clear_teximage_fields(texImage); 3646 } 3647 else { 3648 /* no error: store the teximage parameters */ 3649 _mesa_init_teximage_fields(ctx, texImage, width, height, 3650 depth, border, internalFormat, 3651 MESA_FORMAT_NONE); 3652 } 3653 } 3654 } 3655 else { 3656 /* non-proxy target */ 3657 struct gl_texture_object *texObj; 3658 struct gl_texture_image *texImage; 3659 3660 if (error) { 3661 _mesa_error(ctx, error, "glCompressedTexImage%uD(%s)", dims, reason); 3662 return; 3663 } 3664 3665 texObj = _mesa_get_current_tex_object(ctx, target); 3666 3667 _mesa_lock_texture(ctx, texObj); 3668 { 3669 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 3670 if (!texImage) { 3671 _mesa_error(ctx, GL_OUT_OF_MEMORY, 3672 "glCompressedTexImage%uD", dims); 3673 } 3674 else { 3675 gl_format texFormat; 3676 3677 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 3678 3679 texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, 3680 internalFormat, GL_NONE, 3681 GL_NONE); 3682 3683 if (legal_texture_size(ctx, texFormat, width, height, depth)) { 3684 _mesa_init_teximage_fields(ctx, texImage, 3685 width, height, depth, 3686 border, internalFormat, texFormat); 3687 3688 ctx->Driver.CompressedTexImage(ctx, dims, texImage, imageSize, 3689 data); 3690 3691 check_gen_mipmap(ctx, target, texObj, level); 3692 3693 _mesa_dirty_texobj(ctx, texObj, GL_TRUE); 3694 } 3695 else { 3696 _mesa_error(ctx, GL_OUT_OF_MEMORY, 3697 "glCompressedTexImage%uD", dims); 3698 } 3699 } 3700 } 3701 _mesa_unlock_texture(ctx, texObj); 3702 } 3703} 3704 3705 3706void GLAPIENTRY 3707_mesa_CompressedTexImage1DARB(GLenum target, GLint level, 3708 GLenum internalFormat, GLsizei width, 3709 GLint border, GLsizei imageSize, 3710 const GLvoid *data) 3711{ 3712 GET_CURRENT_CONTEXT(ctx); 3713 compressedteximage(ctx, 1, target, level, internalFormat, 3714 width, 1, 1, border, imageSize, data); 3715} 3716 3717 3718void GLAPIENTRY 3719_mesa_CompressedTexImage2DARB(GLenum target, GLint level, 3720 GLenum internalFormat, GLsizei width, 3721 GLsizei height, GLint border, GLsizei imageSize, 3722 const GLvoid *data) 3723{ 3724 GET_CURRENT_CONTEXT(ctx); 3725 compressedteximage(ctx, 2, target, level, internalFormat, 3726 width, height, 1, border, imageSize, data); 3727} 3728 3729 3730void GLAPIENTRY 3731_mesa_CompressedTexImage3DARB(GLenum target, GLint level, 3732 GLenum internalFormat, GLsizei width, 3733 GLsizei height, GLsizei depth, GLint border, 3734 GLsizei imageSize, const GLvoid *data) 3735{ 3736 GET_CURRENT_CONTEXT(ctx); 3737 compressedteximage(ctx, 3, target, level, internalFormat, 3738 width, height, depth, border, imageSize, data); 3739} 3740 3741 3742/** 3743 * Common helper for glCompressedTexSubImage1/2/3D(). 3744 */ 3745static void 3746compressed_tex_sub_image(GLuint dims, GLenum target, GLint level, 3747 GLint xoffset, GLint yoffset, GLint zoffset, 3748 GLsizei width, GLsizei height, GLsizei depth, 3749 GLenum format, GLsizei imageSize, const GLvoid *data) 3750{ 3751 struct gl_texture_object *texObj; 3752 struct gl_texture_image *texImage; 3753 GLenum error; 3754 GET_CURRENT_CONTEXT(ctx); 3755 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3756 3757 error = compressed_subtexture_error_check(ctx, dims, target, level, 3758 xoffset, 0, 0, /* pos */ 3759 width, height, depth, /* size */ 3760 format, imageSize); 3761 if (error) { 3762 _mesa_error(ctx, error, "glCompressedTexSubImage%uD", dims); 3763 return; 3764 } 3765 3766 texObj = _mesa_get_current_tex_object(ctx, target); 3767 3768 _mesa_lock_texture(ctx, texObj); 3769 { 3770 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3771 assert(texImage); 3772 3773 if (compressed_subtexture_error_check2(ctx, dims, width, height, depth, 3774 format, texImage)) { 3775 /* error was recorded */ 3776 } 3777 else if (width > 0 && height > 0 && depth > 0) { 3778 ctx->Driver.CompressedTexSubImage(ctx, dims, texImage, 3779 xoffset, yoffset, zoffset, 3780 width, height, depth, 3781 format, imageSize, data); 3782 3783 check_gen_mipmap(ctx, target, texObj, level); 3784 3785 ctx->NewState |= _NEW_TEXTURE; 3786 } 3787 } 3788 _mesa_unlock_texture(ctx, texObj); 3789} 3790 3791 3792void GLAPIENTRY 3793_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, 3794 GLsizei width, GLenum format, 3795 GLsizei imageSize, const GLvoid *data) 3796{ 3797 compressed_tex_sub_image(1, target, level, xoffset, 0, 0, width, 1, 1, 3798 format, imageSize, data); 3799} 3800 3801 3802void GLAPIENTRY 3803_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, 3804 GLint yoffset, GLsizei width, GLsizei height, 3805 GLenum format, GLsizei imageSize, 3806 const GLvoid *data) 3807{ 3808 compressed_tex_sub_image(2, target, level, xoffset, yoffset, 0, 3809 width, height, 1, format, imageSize, data); 3810} 3811 3812 3813void GLAPIENTRY 3814_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, 3815 GLint yoffset, GLint zoffset, GLsizei width, 3816 GLsizei height, GLsizei depth, GLenum format, 3817 GLsizei imageSize, const GLvoid *data) 3818{ 3819 compressed_tex_sub_image(3, target, level, xoffset, yoffset, zoffset, 3820 width, height, depth, format, imageSize, data); 3821} 3822 3823static gl_format 3824get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) 3825{ 3826 switch (internalFormat) { 3827 case GL_ALPHA8: 3828 return MESA_FORMAT_A8; 3829 case GL_ALPHA16: 3830 return MESA_FORMAT_A16; 3831 case GL_ALPHA16F_ARB: 3832 return MESA_FORMAT_ALPHA_FLOAT16; 3833 case GL_ALPHA32F_ARB: 3834 return MESA_FORMAT_ALPHA_FLOAT32; 3835 case GL_ALPHA8I_EXT: 3836 return MESA_FORMAT_ALPHA_INT8; 3837 case GL_ALPHA16I_EXT: 3838 return MESA_FORMAT_ALPHA_INT16; 3839 case GL_ALPHA32I_EXT: 3840 return MESA_FORMAT_ALPHA_INT32; 3841 case GL_ALPHA8UI_EXT: 3842 return MESA_FORMAT_ALPHA_UINT8; 3843 case GL_ALPHA16UI_EXT: 3844 return MESA_FORMAT_ALPHA_UINT16; 3845 case GL_ALPHA32UI_EXT: 3846 return MESA_FORMAT_ALPHA_UINT32; 3847 case GL_LUMINANCE8: 3848 return MESA_FORMAT_L8; 3849 case GL_LUMINANCE16: 3850 return MESA_FORMAT_L16; 3851 case GL_LUMINANCE16F_ARB: 3852 return MESA_FORMAT_LUMINANCE_FLOAT16; 3853 case GL_LUMINANCE32F_ARB: 3854 return MESA_FORMAT_LUMINANCE_FLOAT32; 3855 case GL_LUMINANCE8I_EXT: 3856 return MESA_FORMAT_LUMINANCE_INT8; 3857 case GL_LUMINANCE16I_EXT: 3858 return MESA_FORMAT_LUMINANCE_INT16; 3859 case GL_LUMINANCE32I_EXT: 3860 return MESA_FORMAT_LUMINANCE_INT32; 3861 case GL_LUMINANCE8UI_EXT: 3862 return MESA_FORMAT_LUMINANCE_UINT8; 3863 case GL_LUMINANCE16UI_EXT: 3864 return MESA_FORMAT_LUMINANCE_UINT16; 3865 case GL_LUMINANCE32UI_EXT: 3866 return MESA_FORMAT_LUMINANCE_UINT32; 3867 case GL_LUMINANCE8_ALPHA8: 3868 return MESA_FORMAT_AL88; 3869 case GL_LUMINANCE16_ALPHA16: 3870 return MESA_FORMAT_AL1616; 3871 case GL_LUMINANCE_ALPHA16F_ARB: 3872 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16; 3873 case GL_LUMINANCE_ALPHA32F_ARB: 3874 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32; 3875 case GL_LUMINANCE_ALPHA8I_EXT: 3876 return MESA_FORMAT_LUMINANCE_ALPHA_INT8; 3877 case GL_LUMINANCE_ALPHA16I_EXT: 3878 return MESA_FORMAT_LUMINANCE_ALPHA_INT8; 3879 case GL_LUMINANCE_ALPHA32I_EXT: 3880 return MESA_FORMAT_LUMINANCE_ALPHA_INT16; 3881 case GL_LUMINANCE_ALPHA8UI_EXT: 3882 return MESA_FORMAT_LUMINANCE_ALPHA_UINT8; 3883 case GL_LUMINANCE_ALPHA16UI_EXT: 3884 return MESA_FORMAT_LUMINANCE_ALPHA_UINT16; 3885 case GL_LUMINANCE_ALPHA32UI_EXT: 3886 return MESA_FORMAT_LUMINANCE_ALPHA_UINT32; 3887 case GL_INTENSITY8: 3888 return MESA_FORMAT_I8; 3889 case GL_INTENSITY16: 3890 return MESA_FORMAT_I16; 3891 case GL_INTENSITY16F_ARB: 3892 return MESA_FORMAT_INTENSITY_FLOAT16; 3893 case GL_INTENSITY32F_ARB: 3894 return MESA_FORMAT_INTENSITY_FLOAT32; 3895 case GL_INTENSITY8I_EXT: 3896 return MESA_FORMAT_INTENSITY_INT8; 3897 case GL_INTENSITY16I_EXT: 3898 return MESA_FORMAT_INTENSITY_INT16; 3899 case GL_INTENSITY32I_EXT: 3900 return MESA_FORMAT_INTENSITY_INT32; 3901 case GL_INTENSITY8UI_EXT: 3902 return MESA_FORMAT_INTENSITY_UINT8; 3903 case GL_INTENSITY16UI_EXT: 3904 return MESA_FORMAT_INTENSITY_UINT16; 3905 case GL_INTENSITY32UI_EXT: 3906 return MESA_FORMAT_INTENSITY_UINT32; 3907 case GL_RGBA8: 3908 return MESA_FORMAT_RGBA8888_REV; 3909 case GL_RGBA16: 3910 return MESA_FORMAT_RGBA_16; 3911 case GL_RGBA16F_ARB: 3912 return MESA_FORMAT_RGBA_FLOAT16; 3913 case GL_RGBA32F_ARB: 3914 return MESA_FORMAT_RGBA_FLOAT32; 3915 case GL_RGBA8I_EXT: 3916 return MESA_FORMAT_RGBA_INT8; 3917 case GL_RGBA16I_EXT: 3918 return MESA_FORMAT_RGBA_INT16; 3919 case GL_RGBA32I_EXT: 3920 return MESA_FORMAT_RGBA_INT32; 3921 case GL_RGBA8UI_EXT: 3922 return MESA_FORMAT_RGBA_UINT8; 3923 case GL_RGBA16UI_EXT: 3924 return MESA_FORMAT_RGBA_UINT16; 3925 case GL_RGBA32UI_EXT: 3926 return MESA_FORMAT_RGBA_UINT32; 3927 3928 case GL_RG8: 3929 return MESA_FORMAT_GR88; 3930 case GL_RG16: 3931 return MESA_FORMAT_RG1616; 3932 case GL_RG16F: 3933 return MESA_FORMAT_RG_FLOAT16; 3934 case GL_RG32F: 3935 return MESA_FORMAT_RG_FLOAT32; 3936 case GL_RG8I: 3937 return MESA_FORMAT_RG_INT8; 3938 case GL_RG16I: 3939 return MESA_FORMAT_RG_INT16; 3940 case GL_RG32I: 3941 return MESA_FORMAT_RG_INT32; 3942 case GL_RG8UI: 3943 return MESA_FORMAT_RG_UINT8; 3944 case GL_RG16UI: 3945 return MESA_FORMAT_RG_UINT16; 3946 case GL_RG32UI: 3947 return MESA_FORMAT_RG_UINT32; 3948 3949 case GL_R8: 3950 return MESA_FORMAT_R8; 3951 case GL_R16: 3952 return MESA_FORMAT_R16; 3953 case GL_R16F: 3954 return MESA_FORMAT_R_FLOAT16; 3955 case GL_R32F: 3956 return MESA_FORMAT_R_FLOAT32; 3957 case GL_R8I: 3958 return MESA_FORMAT_R_INT8; 3959 case GL_R16I: 3960 return MESA_FORMAT_R_INT16; 3961 case GL_R32I: 3962 return MESA_FORMAT_R_INT32; 3963 case GL_R8UI: 3964 return MESA_FORMAT_R_UINT8; 3965 case GL_R16UI: 3966 return MESA_FORMAT_R_UINT16; 3967 case GL_R32UI: 3968 return MESA_FORMAT_R_UINT32; 3969 3970 default: 3971 return MESA_FORMAT_NONE; 3972 } 3973} 3974 3975static gl_format 3976validate_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) 3977{ 3978 gl_format format = get_texbuffer_format(ctx, internalFormat); 3979 GLenum datatype; 3980 3981 if (format == MESA_FORMAT_NONE) 3982 return MESA_FORMAT_NONE; 3983 3984 datatype = _mesa_get_format_datatype(format); 3985 if (datatype == GL_FLOAT && !ctx->Extensions.ARB_texture_float) 3986 return MESA_FORMAT_NONE; 3987 3988 if (datatype == GL_HALF_FLOAT && !ctx->Extensions.ARB_half_float_pixel) 3989 return MESA_FORMAT_NONE; 3990 3991 /* The GL_ARB_texture_rg and GL_ARB_texture_buffer_object specs don't make 3992 * any mention of R/RG formats, but they appear in the GL 3.1 core 3993 * specification. 3994 */ 3995 if (ctx->Version <= 30) { 3996 GLenum base_format = _mesa_get_format_base_format(format); 3997 3998 if (base_format == GL_R || base_format == GL_RG) 3999 return MESA_FORMAT_NONE; 4000 } 4001 return format; 4002} 4003 4004 4005/** GL_ARB_texture_buffer_object */ 4006void GLAPIENTRY 4007_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer) 4008{ 4009 struct gl_texture_object *texObj; 4010 struct gl_buffer_object *bufObj; 4011 gl_format format; 4012 4013 GET_CURRENT_CONTEXT(ctx); 4014 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 4015 4016 if (!ctx->Extensions.ARB_texture_buffer_object) { 4017 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer"); 4018 return; 4019 } 4020 4021 if (target != GL_TEXTURE_BUFFER_ARB) { 4022 _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(target)"); 4023 return; 4024 } 4025 4026 format = validate_texbuffer_format(ctx, internalFormat); 4027 if (format == MESA_FORMAT_NONE) { 4028 _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(internalFormat 0x%x)", 4029 internalFormat); 4030 return; 4031 } 4032 4033 bufObj = _mesa_lookup_bufferobj(ctx, buffer); 4034 if (buffer && !bufObj) { 4035 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer(buffer %u)", buffer); 4036 return; 4037 } 4038 4039 texObj = _mesa_get_current_tex_object(ctx, target); 4040 4041 _mesa_lock_texture(ctx, texObj); 4042 { 4043 _mesa_reference_buffer_object(ctx, &texObj->BufferObject, bufObj); 4044 texObj->BufferObjectFormat = internalFormat; 4045 texObj->_BufferObjectFormat = format; 4046 } 4047 _mesa_unlock_texture(ctx, texObj); 4048} 4049