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