teximage.c revision 3c59febf05e6af80d63e5b9a478a11b275ac429c
1b1928704201034c785a26296a49f69355eb56a05Nick Lewycky/* 2b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * mesa 3-D graphics library 3b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * Version: 7.6 4b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * 5b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 7b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * 8b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * Permission is hereby granted, free of charge, to any person obtaining a 9b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * copy of this software and associated documentation files (the "Software"), 10b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * to deal in the Software without restriction, including without limitation 11b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * and/or sell copies of the Software, and to permit persons to whom the 13b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * Software is furnished to do so, subject to the following conditions: 14b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * 15b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * The above copyright notice and this permission notice shall be included 16b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * in all copies or substantial portions of the Software. 17b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * 18b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2306cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24b1928704201034c785a26296a49f69355eb56a05Nick Lewycky */ 25b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 26b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 27d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth/** 280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth * \file teximage.c 290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth * Texture image-related functions. 300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth */ 31d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth 32a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky 3306cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "glheader.h" 3406cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "bufferobj.h" 3539c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling#include "context.h" 3606cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "enums.h" 3706cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "fbobject.h" 3806cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "framebuffer.h" 3906cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "hash.h" 40b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "image.h" 41b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "imports.h" 42b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "macros.h" 43b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "state.h" 44a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky#include "texcompress.h" 45a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky#include "texfetch.h" 46a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky#include "teximage.h" 47a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky#include "texstate.h" 48a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky#include "texpal.h" 49a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky#include "mtypes.h" 50a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky 51a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky 52a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky/** 53a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky * State changes which we care about for glCopyTex[Sub]Image() calls. 54a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky * In particular, we care about pixel transfer state and buffer state 55a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky * (such as glReadBuffer to make sure we read from the right renderbuffer). 56a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky */ 57a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky#define NEW_COPY_TEX_STATE (_MESA_NEW_TRANSFER_STATE | \ 58a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky _NEW_BUFFERS | \ 59a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky _NEW_PIXEL) 60a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky 61a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky 62a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky 63a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky/** 64b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * We allocate texture memory on 512-byte boundaries so we can use MMX/SSE 65b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * elsewhere. 66b1928704201034c785a26296a49f69355eb56a05Nick Lewycky */ 67b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyvoid * 68a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky_mesa_alloc_texmemory(GLsizei bytes) 69a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky{ 70a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky return _mesa_align_malloc(bytes, 512); 71a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky} 72a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky 73a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky 74a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky/** 75a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky * Free texture memory allocated with _mesa_alloc_texmemory() 76a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky */ 77a204ef3168c8804808c716115ba915c89d8849b9Nick Lewyckyvoid 78a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky_mesa_free_texmemory(void *m) 79a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky{ 80a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky _mesa_align_free(m); 81a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky} 82a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky 83a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky 84b1928704201034c785a26296a49f69355eb56a05Nick Lewycky/* 85b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * Compute floor(log_base_2(n)). 86b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * If n < 0 return -1. 87b1928704201034c785a26296a49f69355eb56a05Nick Lewycky */ 88b1928704201034c785a26296a49f69355eb56a05Nick Lewyckystatic int 89a204ef3168c8804808c716115ba915c89d8849b9Nick Lewyckylogbase2( int n ) 90b1928704201034c785a26296a49f69355eb56a05Nick Lewycky{ 91269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky GLint i = 1; 92269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky GLint log2 = 0; 9364a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky 9464a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky if (n < 0) 95b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return -1; 960c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 970c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky if (n == 0) 98f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel return 0; 990c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 100b1928704201034c785a26296a49f69355eb56a05Nick Lewycky while ( n > i ) { 101b1928704201034c785a26296a49f69355eb56a05Nick Lewycky i *= 2; 10277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling log2++; 103b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 104b1928704201034c785a26296a49f69355eb56a05Nick Lewycky if (i != n) { 10518764716861243c58a711a92190624dc2f6aafc9Bill Wendling return log2 - 1; 106d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling } 107b1928704201034c785a26296a49f69355eb56a05Nick Lewycky else { 108b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return log2; 1091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 1101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 1111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 1121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 1131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 1141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky/** 1151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * Return the simple base format for a given internal texture format. 1161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * For example, given GL_LUMINANCE12_ALPHA4, return GL_LUMINANCE_ALPHA. 11764a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky * 11864a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky * \param ctx GL context. 1191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * \param internalFormat the internal texture format token or 1, 2, 3, or 4. 120b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * 121b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * \return the corresponding \u base internal format (GL_ALPHA, GL_LUMINANCE, 122d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA), or -1 if invalid enum. 123d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling * 124d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling * This is the format which is used during texture application (i.e. the 12577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling * texture format and env mode determine the arithmetic used. 126b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * 12739c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling * XXX this could be static 12839c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling */ 129269687fa350c1aa044bc063c64362a04ecabaa33Nick LewyckyGLint 130a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky_mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) 131a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky{ 132a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky switch (internalFormat) { 133a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky case GL_ALPHA: 134a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky case GL_ALPHA4: 1351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_ALPHA8: 136b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_ALPHA12: 137b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_ALPHA16: 138b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return GL_ALPHA; 139b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case 1: 140b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_LUMINANCE: 141b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_LUMINANCE4: 142b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_LUMINANCE8: 143b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_LUMINANCE12: 144a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky case GL_LUMINANCE16: 145a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky return GL_LUMINANCE; 146a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky case 2: 147b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_LUMINANCE_ALPHA: 1485d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky case GL_LUMINANCE4_ALPHA4: 1495d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky case GL_LUMINANCE6_ALPHA2: 1505d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky case GL_LUMINANCE8_ALPHA8: 1515d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky case GL_LUMINANCE12_ALPHA4: 1525d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky case GL_LUMINANCE12_ALPHA12: 1535d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky case GL_LUMINANCE16_ALPHA16: 154b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return GL_LUMINANCE_ALPHA; 155b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_INTENSITY: 156b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_INTENSITY4: 1571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_INTENSITY8: 1581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_INTENSITY12: 1591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_INTENSITY16: 1601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GL_INTENSITY; 161b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case 3: 162b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGB: 163b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_R3_G3_B2: 1641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_RGB4: 1651790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_RGB5: 166b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGB8: 167b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGB10: 1681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_RGB12: 1691790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_RGB16: 170b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return GL_RGB; 171b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case 4: 172b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGBA: 173b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGBA2: 1741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_RGBA4: 175b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGB5_A1: 17617df2c3240837b4382898ead8c3ead407a338520Nick Lewycky case GL_RGBA8: 17717df2c3240837b4382898ead8c3ead407a338520Nick Lewycky case GL_RGB10_A2: 178d363ff334d796c7f3df834d928a10d88ed758454Nick Lewycky case GL_RGBA12: 179b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGBA16: 180b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return GL_RGBA; 1811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky default: 1821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ; /* fallthrough */ 1831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 1841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 185b1928704201034c785a26296a49f69355eb56a05Nick Lewycky if (ctx->Extensions.EXT_paletted_texture) { 186b1928704201034c785a26296a49f69355eb56a05Nick Lewycky switch (internalFormat) { 1877a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky case GL_COLOR_INDEX: 1887a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky case GL_COLOR_INDEX1_EXT: 1897a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky case GL_COLOR_INDEX2_EXT: 190b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_COLOR_INDEX4_EXT: 191b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_COLOR_INDEX8_EXT: 192b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_COLOR_INDEX12_EXT: 193b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_COLOR_INDEX16_EXT: 1941790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GL_COLOR_INDEX; 1951790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky default: 1961790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ; /* fallthrough */ 1971790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 198b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 199b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 200b1928704201034c785a26296a49f69355eb56a05Nick Lewycky if (ctx->Extensions.ARB_depth_texture) { 201b1928704201034c785a26296a49f69355eb56a05Nick Lewycky switch (internalFormat) { 202b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_DEPTH_COMPONENT: 20316c19a155c65fd41865562fe4e678ef32728510bDevang Patel case GL_DEPTH_COMPONENT16: 20416c19a155c65fd41865562fe4e678ef32728510bDevang Patel case GL_DEPTH_COMPONENT24: 205b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_DEPTH_COMPONENT32: 206b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return GL_DEPTH_COMPONENT; 2071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky default: 2081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ; /* fallthrough */ 209b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 210b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 2111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 212bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky switch (internalFormat) { 21316c19a155c65fd41865562fe4e678ef32728510bDevang Patel case GL_COMPRESSED_ALPHA: 214b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return GL_ALPHA; 215b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_COMPRESSED_LUMINANCE: 21616c19a155c65fd41865562fe4e678ef32728510bDevang Patel return GL_LUMINANCE; 21716c19a155c65fd41865562fe4e678ef32728510bDevang Patel case GL_COMPRESSED_LUMINANCE_ALPHA: 21816c19a155c65fd41865562fe4e678ef32728510bDevang Patel return GL_LUMINANCE_ALPHA; 21916c19a155c65fd41865562fe4e678ef32728510bDevang Patel case GL_COMPRESSED_INTENSITY: 22016c19a155c65fd41865562fe4e678ef32728510bDevang Patel return GL_INTENSITY; 22116c19a155c65fd41865562fe4e678ef32728510bDevang Patel case GL_COMPRESSED_RGB: 222b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return GL_RGB; 22316c19a155c65fd41865562fe4e678ef32728510bDevang Patel case GL_COMPRESSED_RGBA: 22416c19a155c65fd41865562fe4e678ef32728510bDevang Patel return GL_RGBA; 225b1928704201034c785a26296a49f69355eb56a05Nick Lewycky default: 226b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ; /* fallthrough */ 227b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 228680018ff8965610b3f1c976b0be1dfd45116b218Devang Patel 22916c19a155c65fd41865562fe4e678ef32728510bDevang Patel if (ctx->Extensions.TDFX_texture_compression_FXT1) { 2301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky switch (internalFormat) { 231b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_COMPRESSED_RGB_FXT1_3DFX: 232b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return GL_RGB; 233b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_COMPRESSED_RGBA_FXT1_3DFX: 234b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return GL_RGBA; 235b1928704201034c785a26296a49f69355eb56a05Nick Lewycky default: 236b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ; /* fallthrough */ 237b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 23868155d31cd0175be89e26ee68387cb411fca537bDevang Patel } 2391790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 2401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (ctx->Extensions.EXT_texture_compression_s3tc) { 24116c19a155c65fd41865562fe4e678ef32728510bDevang Patel switch (internalFormat) { 242b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 2431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GL_RGB; 244b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 245b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 2461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: 2471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GL_RGBA; 248b1928704201034c785a26296a49f69355eb56a05Nick Lewycky default: 249b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ; /* fallthrough */ 2501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 2511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 2521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 2531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (ctx->Extensions.S3_s3tc) { 25416c19a155c65fd41865562fe4e678ef32728510bDevang Patel switch (internalFormat) { 255b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGB_S3TC: 256b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGB4_S3TC: 2571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GL_RGB; 2581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_RGBA_S3TC: 2591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_RGBA4_S3TC: 2601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GL_RGBA; 26116c19a155c65fd41865562fe4e678ef32728510bDevang Patel default: 26216c19a155c65fd41865562fe4e678ef32728510bDevang Patel ; /* fallthrough */ 2631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 2641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 265b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 266b1928704201034c785a26296a49f69355eb56a05Nick Lewycky if (ctx->Extensions.MESA_ycbcr_texture) { 267b1928704201034c785a26296a49f69355eb56a05Nick Lewycky if (internalFormat == GL_YCBCR_MESA) 2681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GL_YCBCR_MESA; 269b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 270b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 271b1928704201034c785a26296a49f69355eb56a05Nick Lewycky if (ctx->Extensions.ARB_texture_float) { 272b1928704201034c785a26296a49f69355eb56a05Nick Lewycky switch (internalFormat) { 273b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_ALPHA16F_ARB: 2741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_ALPHA32F_ARB: 2751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GL_ALPHA; 276b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGBA16F_ARB: 277b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGBA32F_ARB: 278b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return GL_RGBA; 2791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_RGB16F_ARB: 2801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_RGB32F_ARB: 2811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GL_RGB; 282b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_INTENSITY16F_ARB: 283b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_INTENSITY32F_ARB: 284b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return GL_INTENSITY; 285b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_LUMINANCE16F_ARB: 286b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_LUMINANCE32F_ARB: 287b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return GL_LUMINANCE; 288b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_LUMINANCE_ALPHA16F_ARB: 289d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky case GL_LUMINANCE_ALPHA32F_ARB: 290a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky return GL_LUMINANCE_ALPHA; 291b1928704201034c785a26296a49f69355eb56a05Nick Lewycky default: 292b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ; /* fallthrough */ 293b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 294bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } 295b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 296b1928704201034c785a26296a49f69355eb56a05Nick Lewycky if (ctx->Extensions.ATI_envmap_bumpmap) { 2971790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky switch (internalFormat) { 298b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_DUDV_ATI: 2991790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_DU8DV8_ATI: 3001790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GL_DUDV_ATI; 3011790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky default: 3025d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky ; /* fallthrough */ 3031790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 304a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky } 305bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 3061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (ctx->Extensions.MESA_texture_signed_rgba) { 3071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky switch (internalFormat) { 308bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_RGBA_SNORM: 309a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky case GL_RGBA8_SNORM: 310bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky return GL_RGBA; 3115d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky default: 3121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ; /* fallthrough */ 3131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 314b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 315b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 316b1928704201034c785a26296a49f69355eb56a05Nick Lewycky if (ctx->Extensions.EXT_packed_depth_stencil) { 3171790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky switch (internalFormat) { 3181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_DEPTH_STENCIL_EXT: 319b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_DEPTH24_STENCIL8_EXT: 320b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return GL_DEPTH_STENCIL_EXT; 3211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky default: 3221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ; /* fallthrough */ 323b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 324b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 3251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 3261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky#if FEATURE_EXT_texture_sRGB 327a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky if (ctx->Extensions.EXT_texture_sRGB) { 328a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky switch (internalFormat) { 3291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_SRGB_EXT: 330b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_SRGB8_EXT: 3311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_COMPRESSED_SRGB_EXT: 3321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: 3331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GL_RGB; 3341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_SRGB_ALPHA_EXT: 335b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_SRGB8_ALPHA8_EXT: 336bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_COMPRESSED_SRGB_ALPHA_EXT: 337b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: 338b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: 3391790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: 3401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GL_RGBA; 3411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_SLUMINANCE_ALPHA_EXT: 3421790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_SLUMINANCE8_ALPHA8_EXT: 3431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_COMPRESSED_SLUMINANCE_EXT: 3441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT: 3451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GL_LUMINANCE_ALPHA; 3461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_SLUMINANCE_EXT: 3471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_SLUMINANCE8_EXT: 348bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky return GL_LUMINANCE; 349bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky default: 3501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ; /* fallthrough */ 3511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 352b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 353b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#endif /* FEATURE_EXT_texture_sRGB */ 354b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 355b1928704201034c785a26296a49f69355eb56a05Nick Lewycky if (ctx->Extensions.EXT_texture_integer) { 3561790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky switch (internalFormat) { 3571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_RGBA8UI_EXT: 3581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_RGBA16UI_EXT: 359b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGBA32UI_EXT: 360b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGBA8I_EXT: 361b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGBA16I_EXT: 362b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGBA32I_EXT: 3631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GL_RGBA; 3641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_RGB8UI_EXT: 365b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGB16UI_EXT: 366b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGB32UI_EXT: 367b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_RGB8I_EXT: 36839c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling case GL_RGB16I_EXT: 36939c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling case GL_RGB32I_EXT: 370269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky return GL_RGB; 371269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky case GL_ALPHA8UI_EXT: 372269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky case GL_ALPHA16UI_EXT: 373269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky case GL_ALPHA32UI_EXT: 374fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky case GL_ALPHA8I_EXT: 375269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky case GL_ALPHA16I_EXT: 376fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky case GL_ALPHA32I_EXT: 377fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky return GL_ALPHA; 3786e5190c193f6267893daf6943af88e95039e739cBill Wendling case GL_INTENSITY8UI_EXT: 3796e5190c193f6267893daf6943af88e95039e739cBill Wendling case GL_INTENSITY16UI_EXT: 3806e5190c193f6267893daf6943af88e95039e739cBill Wendling case GL_INTENSITY32UI_EXT: 381fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky case GL_INTENSITY8I_EXT: 382269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky case GL_INTENSITY16I_EXT: 383269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky case GL_INTENSITY32I_EXT: 384fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky return GL_INTENSITY; 3856e5190c193f6267893daf6943af88e95039e739cBill Wendling case GL_LUMINANCE8UI_EXT: 386fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky case GL_LUMINANCE16UI_EXT: 38739c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling case GL_LUMINANCE32UI_EXT: 38839c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling case GL_LUMINANCE8I_EXT: 38939c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling case GL_LUMINANCE16I_EXT: 39039c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling case GL_LUMINANCE32I_EXT: 39139c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling return GL_LUMINANCE; 39239c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling case GL_LUMINANCE_ALPHA8UI_EXT: 39339c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling case GL_LUMINANCE_ALPHA16UI_EXT: 394269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky case GL_LUMINANCE_ALPHA32UI_EXT: 395269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky case GL_LUMINANCE_ALPHA8I_EXT: 3960c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky case GL_LUMINANCE_ALPHA16I_EXT: 3971790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_LUMINANCE_ALPHA32I_EXT: 3980c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky return GL_LUMINANCE_ALPHA; 3990c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky default: 400a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky ; /* fallthrough */ 401a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky } 402a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky } 4030c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 4040c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky if (ctx->Extensions.ARB_texture_rg) { 40564a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky switch (internalFormat) { 406f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel case GL_R16F: 407bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky /* R16F depends on both ARB_half_float_pixel and ARB_texture_float. 408bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky */ 409bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!ctx->Extensions.ARB_half_float_pixel) 410bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky break; 411bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky /* FALLTHROUGH */ 412bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_R32F: 413bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!ctx->Extensions.ARB_texture_float) 414bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky break; 415bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky return GL_RED; 41639c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling case GL_R8I: 417bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_R8UI: 418d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky case GL_R16I: 419a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky case GL_R16UI: 420d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky case GL_R32I: 421bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_R32UI: 422bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!ctx->Extensions.EXT_texture_integer) 423bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky break; 424bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky /* FALLTHROUGH */ 425bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_R8: 426bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_R16: 427bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_RED: 428bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_COMPRESSED_RED: 429a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky return GL_RED; 430bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 431bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_RG16F: 432bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky /* RG16F depends on both ARB_half_float_pixel and ARB_texture_float. 433bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky */ 434bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!ctx->Extensions.ARB_half_float_pixel) 435bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky break; 436bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky /* FALLTHROUGH */ 437f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel case GL_RG32F: 438bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!ctx->Extensions.ARB_texture_float) 439bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky break; 440bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky return GL_RG; 441bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_RG8I: 442bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_RG8UI: 443bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_RG16I: 444bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_RG16UI: 445bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_RG32I: 446bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_RG32UI: 447bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!ctx->Extensions.EXT_texture_integer) 448bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky break; 449bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky /* FALLTHROUGH */ 450bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_RG: 451bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_RG8: 452bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky case GL_RG16: 453b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_COMPRESSED_RG: 454b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return GL_RG; 455bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky default: 456b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ; /* fallthrough */ 457bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } 458bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } 459b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 460b1928704201034c785a26296a49f69355eb56a05Nick Lewycky if (ctx->Extensions.EXT_texture_shared_exponent) { 461b1928704201034c785a26296a49f69355eb56a05Nick Lewycky switch (internalFormat) { 462f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel case GL_RGB9_E5_EXT: 463f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel return GL_RGB; 464f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel default: 465f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ; /* fallthrough */ 466f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 46777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling } 468f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 469f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (ctx->Extensions.EXT_packed_float) { 470f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel switch (internalFormat) { 471f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel case GL_R11F_G11F_B10F_EXT: 472f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel return GL_RGB; 473f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel default: 474f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ; /* fallthrough */ 475f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 476f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 477f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 478f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (ctx->Extensions.ARB_depth_buffer_float) { 479f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel switch (internalFormat) { 480f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel case GL_DEPTH_COMPONENT32F: 481f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel return GL_DEPTH_COMPONENT; 482f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel case GL_DEPTH32F_STENCIL8: 483f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel return GL_DEPTH_STENCIL; 484f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel default: 485f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ; /* fallthrough */ 486f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 487f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 4881790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 489f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (ctx->Extensions.ARB_texture_compression_rgtc) { 4901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky switch (internalFormat) { 491b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_COMPRESSED_RED_RGTC1: 4921790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_COMPRESSED_SIGNED_RED_RGTC1: 493ce718ff9f42c7da092eaa01dd0242e8d5ba84713Hans Wennborg return GL_RED; 494f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel case GL_COMPRESSED_RG_RGTC2: 495f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel case GL_COMPRESSED_SIGNED_RG_RGTC2: 496f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel return GL_RG; 497f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel default: 498f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ; /* fallthrough */ 499f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 500f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 501f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 502f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel return -1; /* error */ 503f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel} 504f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 505f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 506f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel/** 507f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel * For cube map faces, return a face index in [0,5]. 508f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel * For other targets return 0; 509f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel */ 510bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick LewyckyGLuint 511f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel_mesa_tex_target_to_face(GLenum target) 512f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel{ 513bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 514bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) 515bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; 516f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel else 517bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky return 0; 518f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel} 519f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 520f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 521bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky 522f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel/** 523f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel * Store a gl_texture_image pointer in a gl_texture_object structure 524f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel * according to the target and level parameters. 525f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel * 526f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel * \param tObj texture object. 527f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel * \param target texture target. 528f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel * \param level image level. 529b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * \param texImage texture image. 530b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * 531f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel * This was basically prompted by the introduction of cube maps. 532f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel */ 533f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelvoid 5341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky_mesa_set_tex_image(struct gl_texture_object *tObj, 5351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GLenum target, GLint level, 536f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel struct gl_texture_image *texImage) 537f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel{ 538f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel const GLuint face = _mesa_tex_target_to_face(target); 539f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 540bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky ASSERT(tObj); 541f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ASSERT(texImage); 542f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ASSERT(target != GL_TEXTURE_RECTANGLE_NV || level == 0); 543f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 54477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling tObj->Image[face][level] = texImage; 54577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 546f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel /* Set the 'back' pointer */ 547f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel texImage->TexObject = tObj; 5481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 5491790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 550c7a884040e4ec7795515978a94803894ad08c4caBill Wendling 551c7a884040e4ec7795515978a94803894ad08c4caBill Wendling/** 55277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling * Allocate a texture image structure. 55377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling * 55477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling * Called via ctx->Driver.NewTextureImage() unless overriden by a device 555f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel * driver. 556b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * 557b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * \return a pointer to gl_texture_image struct with all fields initialized to 5584a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling * zero. 559d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling */ 560d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendlingstruct gl_texture_image * 561d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling_mesa_new_texture_image( struct gl_context *ctx ) 562d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling{ 56318764716861243c58a711a92190624dc2f6aafc9Bill Wendling (void) ctx; 56418764716861243c58a711a92190624dc2f6aafc9Bill Wendling return CALLOC_STRUCT(gl_texture_image); 565d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling} 566d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling 567d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling 568d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling/** 569d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling * Free texture image data. 570d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling * This function is a fallback called via ctx->Driver.FreeTexImageData(). 571d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling * 572d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling * \param texImage texture image. 573d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling * 574d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling * Free the texture image data if it's not marked as client data. 575d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling */ 576d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendlingvoid 577d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling_mesa_free_texture_image_data(struct gl_context *ctx, 5788640c6a5227b75666e02424e2181289692138348Bill Wendling struct gl_texture_image *texImage) 5798640c6a5227b75666e02424e2181289692138348Bill Wendling{ 5808640c6a5227b75666e02424e2181289692138348Bill Wendling (void) ctx; 5818640c6a5227b75666e02424e2181289692138348Bill Wendling 5828640c6a5227b75666e02424e2181289692138348Bill Wendling if (texImage->Data && !texImage->IsClientData) { 5838640c6a5227b75666e02424e2181289692138348Bill Wendling /* free the old texture data */ 5848640c6a5227b75666e02424e2181289692138348Bill Wendling _mesa_free_texmemory(texImage->Data); 5858640c6a5227b75666e02424e2181289692138348Bill Wendling } 5868640c6a5227b75666e02424e2181289692138348Bill Wendling 5878640c6a5227b75666e02424e2181289692138348Bill Wendling texImage->Data = NULL; 588d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling} 589d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling 590d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling 591b1928704201034c785a26296a49f69355eb56a05Nick Lewycky/** 59277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling * Free texture image. 59377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling * 59477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling * \param texImage texture image. 59577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling * 596f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel * Free the texture image structure and the associated image data. 597b1928704201034c785a26296a49f69355eb56a05Nick Lewycky */ 598b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyvoid 5991790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky_mesa_delete_texture_image(struct gl_context *ctx, 6001790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky struct gl_texture_image *texImage) 6011790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky{ 6021790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky /* Free texImage->Data and/or any other driver-specific texture 6031790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * image storage. 6041790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky */ 6051790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ASSERT(ctx->Driver.FreeTexImageData); 6061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ctx->Driver.FreeTexImageData( ctx, texImage ); 6071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 6081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ASSERT(texImage->Data == NULL); 6091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (texImage->ImageOffsets) 6101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky free(texImage->ImageOffsets); 6119e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer free(texImage); 612db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner} 6139e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer 6141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 6159e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer/** 6161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * Test if a target is a proxy target. 6179e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer * 6181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * \param target texture target. 6191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * 6201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise. 6211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky */ 6221790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGLboolean 6231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky_mesa_is_proxy_texture(GLenum target) 6247a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky{ 6251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky /* NUM_TEXTURE_TARGETS should match number of terms below */ 6261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky assert(NUM_TEXTURE_TARGETS == 7); 627bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky 628bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky return (target == GL_PROXY_TEXTURE_1D || 6291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky target == GL_PROXY_TEXTURE_2D || 6301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky target == GL_PROXY_TEXTURE_3D || 6311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky target == GL_PROXY_TEXTURE_CUBE_MAP_ARB || 6321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky target == GL_PROXY_TEXTURE_RECTANGLE_NV || 6331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky target == GL_PROXY_TEXTURE_1D_ARRAY_EXT || 6341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky target == GL_PROXY_TEXTURE_2D_ARRAY_EXT); 6351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 6361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 6379e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer 6381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky/** 6391790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * Get the texture object that corresponds to the target of the given 6401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * texture unit. 641267010864e139781ef5949939e081c41f954de0aJay Foad * 6421790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * \param ctx GL context. 6431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * \param texUnit texture unit. 6441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * \param target texture target. 6451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * 6461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * \return pointer to the texture object on success, or NULL on failure. 647b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * 648d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky * \sa gl_texture_unit. 649d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky */ 650d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewyckystruct gl_texture_object * 651d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky_mesa_select_tex_object(struct gl_context *ctx, 652d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky const struct gl_texture_unit *texUnit, 6531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GLenum target) 6541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky{ 6551790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky switch (target) { 65677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling case GL_TEXTURE_1D: 65777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling return texUnit->CurrentTex[TEXTURE_1D_INDEX]; 658c7a884040e4ec7795515978a94803894ad08c4caBill Wendling case GL_PROXY_TEXTURE_1D: 65977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]; 660b8bce928f4ffdf50eff69334f3e25b27848536b6Micah Villmow case GL_TEXTURE_2D: 661b8bce928f4ffdf50eff69334f3e25b27848536b6Micah Villmow return texUnit->CurrentTex[TEXTURE_2D_INDEX]; 66277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling case GL_PROXY_TEXTURE_2D: 66377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; 66477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling case GL_TEXTURE_3D: 665b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return texUnit->CurrentTex[TEXTURE_3D_INDEX]; 666b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_PROXY_TEXTURE_3D: 667b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]; 66817d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 6695409a188328d9de3755febc23558d4fc1797d04eNick Lewycky case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 6705409a188328d9de3755febc23558d4fc1797d04eNick Lewycky case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 67117d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 6725409a188328d9de3755febc23558d4fc1797d04eNick Lewycky case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 673c7a884040e4ec7795515978a94803894ad08c4caBill Wendling case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 6741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_TEXTURE_CUBE_MAP_ARB: 675b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return ctx->Extensions.ARB_texture_cube_map 676b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL; 677b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 6785fdd6c8793462549e3593890ec61573da06e3346Jay Foad return ctx->Extensions.ARB_texture_cube_map 679b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL; 680b1928704201034c785a26296a49f69355eb56a05Nick Lewycky case GL_TEXTURE_RECTANGLE_NV: 681b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return ctx->Extensions.NV_texture_rectangle 682d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky ? texUnit->CurrentTex[TEXTURE_RECT_INDEX] : NULL; 6831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky case GL_PROXY_TEXTURE_RECTANGLE_NV: 684b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return ctx->Extensions.NV_texture_rectangle 685b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL; 68618764716861243c58a711a92190624dc2f6aafc9Bill Wendling case GL_TEXTURE_1D_ARRAY_EXT: 68718764716861243c58a711a92190624dc2f6aafc9Bill Wendling return ctx->Extensions.MESA_texture_array 68818764716861243c58a711a92190624dc2f6aafc9Bill Wendling ? texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX] : NULL; 68918764716861243c58a711a92190624dc2f6aafc9Bill Wendling case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 69018764716861243c58a711a92190624dc2f6aafc9Bill Wendling return ctx->Extensions.MESA_texture_array 691d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL; 692d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling case GL_TEXTURE_2D_ARRAY_EXT: 693d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling return ctx->Extensions.MESA_texture_array 694d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling ? texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX] : NULL; 695d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 696b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return ctx->Extensions.MESA_texture_array 697db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL; 6981790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky default: 699b1928704201034c785a26296a49f69355eb56a05Nick Lewycky _mesa_problem(NULL, "bad target in _mesa_select_tex_object()"); 700b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return NULL; 7011790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 7021790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 7031790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 7041790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 7051790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky/** 7061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky * Return pointer to texture object for given target on current texture unit. 7071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky */ 7081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewyckystruct gl_texture_object * 7091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) 7101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky{ 7111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); 7121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return _mesa_select_tex_object(ctx, texUnit, target); 713b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 714d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling 71521b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling 716253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling/** 717253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling * Get a texture image pointer from a texture object, given a texture 718253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling * target and mipmap level. The target and level parameters should 719253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling * have already been error-checked. 720253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling * 721b1928704201034c785a26296a49f69355eb56a05Nick Lewycky * \param ctx GL context. 722034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling * \param texObj texture unit. 723a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky * \param target texture target. 724034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling * \param level image level. 725253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling * 726253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling * \return pointer to the texture image structure, or NULL on failure. 7271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky */ 728b1928704201034c785a26296a49f69355eb56a05Nick Lewyckystruct gl_texture_image * 729b1928704201034c785a26296a49f69355eb56a05Nick Lewycky_mesa_select_tex_image(struct gl_context *ctx, 730b1928704201034c785a26296a49f69355eb56a05Nick Lewycky const struct gl_texture_object *texObj, 731b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GLenum target, GLint level) 732b1928704201034c785a26296a49f69355eb56a05Nick Lewycky{ 733b1928704201034c785a26296a49f69355eb56a05Nick Lewycky const GLuint face = _mesa_tex_target_to_face(target); 734f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 735f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ASSERT(texObj); 736f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ASSERT(level >= 0); 737032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling ASSERT(level < MAX_TEXTURE_LEVELS); 73839c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling 739d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky return texObj->Image[face][level]; 740d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky} 741a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky 7428fa6dc431deb7a9aadc23ec0a7bdcb2d02330972Nick Lewycky 7438fa6dc431deb7a9aadc23ec0a7bdcb2d02330972Nick Lewycky/** 7445d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky * Like _mesa_select_tex_image() but if the image doesn't exist, allocate 7455d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky * it and install it. Only return NULL if passed a bad parameter or run 7465d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky * out of memory. 7475d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky */ 7485d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewyckystruct gl_texture_image * 7495d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky_mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj, 75017d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky GLenum target, GLint level) 7518fa6dc431deb7a9aadc23ec0a7bdcb2d02330972Nick Lewycky{ 752f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel struct gl_texture_image *texImage; 753b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 754f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!texObj) 755bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky return NULL; 756f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 757f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel texImage = _mesa_select_tex_image(ctx, texObj, target, level); 758f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!texImage) { 759b1928704201034c785a26296a49f69355eb56a05Nick Lewycky texImage = ctx->Driver.NewTextureImage(ctx); 760b1928704201034c785a26296a49f69355eb56a05Nick Lewycky if (!texImage) { 761b1928704201034c785a26296a49f69355eb56a05Nick Lewycky _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation"); 7624a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling return NULL; 763d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling } 764b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 76577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling _mesa_set_tex_image(texObj, target, level, texImage); 76677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling } 76777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 76877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling return texImage; 76977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling} 77077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 771034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling 772a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky/** 773034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling * Return pointer to the specified proxy texture image. 77477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling * Note that proxy textures are per-context, not per-texture unit. 77577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling * \return pointer to texture image or NULL if invalid target, invalid 77677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling * level, or out of memory. 77777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling */ 77877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendlingstruct gl_texture_image * 77977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling_mesa_get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level) 78077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling{ 78177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling struct gl_texture_image *texImage; 78277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling GLuint texIndex; 78377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 78477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (level < 0 ) 78577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling return NULL; 78677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 78777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling switch (target) { 788bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky case GL_PROXY_TEXTURE_1D: 78977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (level >= ctx->Const.MaxTextureLevels) 79077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling return NULL; 79177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling texIndex = TEXTURE_1D_INDEX; 79277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling break; 79377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling case GL_PROXY_TEXTURE_2D: 79477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (level >= ctx->Const.MaxTextureLevels) 795bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky return NULL; 79677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling texIndex = TEXTURE_2D_INDEX; 79777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling break; 79877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling case GL_PROXY_TEXTURE_3D: 79977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (level >= ctx->Const.Max3DTextureLevels) 80058591b1647e0f1f213e5acd7bfa87c226ced0033Nick Lewycky return NULL; 80158591b1647e0f1f213e5acd7bfa87c226ced0033Nick Lewycky texIndex = TEXTURE_3D_INDEX; 80258591b1647e0f1f213e5acd7bfa87c226ced0033Nick Lewycky break; 80377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling case GL_PROXY_TEXTURE_CUBE_MAP: 80477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (level >= ctx->Const.MaxCubeTextureLevels) 80577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling return NULL; 80677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling texIndex = TEXTURE_CUBE_INDEX; 80777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling break; 808bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky case GL_PROXY_TEXTURE_RECTANGLE_NV: 80977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (level > 0) 81077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling return NULL; 81177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling texIndex = TEXTURE_RECT_INDEX; 81277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling break; 81377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 81477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (level >= ctx->Const.MaxTextureLevels) 81577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling return NULL; 816253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling texIndex = TEXTURE_1D_ARRAY_INDEX; 817d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling break; 818253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 819253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (level >= ctx->Const.MaxTextureLevels) 820d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling return NULL; 821253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling texIndex = TEXTURE_2D_ARRAY_INDEX; 822253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling break; 823d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling default: 824253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling return NULL; 825253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling } 826253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 827034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling texImage = ctx->Texture.ProxyTex[texIndex]->Image[0][level]; 828a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky if (!texImage) { 829034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling texImage = ctx->Driver.NewTextureImage(ctx); 830253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (!texImage) { 831253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); 832253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling return NULL; 833253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling } 834253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling ctx->Texture.ProxyTex[texIndex]->Image[0][level] = texImage; 835253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling /* Set the 'back' pointer */ 836253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling texImage->TexObject = ctx->Texture.ProxyTex[texIndex]; 837253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling } 838253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling return texImage; 839253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling} 840032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling 841032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling 842032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling/** 843032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling * Get the maximum number of allowed mipmap levels. 844032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling * 845032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling * \param ctx GL context. 846ec3fc2eac0e9203dd1094b9ce458e8c1b42b832fBill Wendling * \param target texture target. 847032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling * 848253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling * \return the maximum number of allowed mipmap levels for the given 849253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling * texture target, or zero if passed a bad target. 850253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling * 851253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling * \sa gl_constants. 852253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling */ 853d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill WendlingGLint 854253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling_mesa_max_texture_levels(struct gl_context *ctx, GLenum target) 855253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling{ 856d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling switch (target) { 857d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling case GL_TEXTURE_1D: 858d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling case GL_PROXY_TEXTURE_1D: 859253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling case GL_TEXTURE_2D: 860 case GL_PROXY_TEXTURE_2D: 861 return ctx->Const.MaxTextureLevels; 862 case GL_TEXTURE_3D: 863 case GL_PROXY_TEXTURE_3D: 864 return ctx->Const.Max3DTextureLevels; 865 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 866 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 867 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 868 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 869 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 870 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 871 case GL_TEXTURE_CUBE_MAP_ARB: 872 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 873 return ctx->Extensions.ARB_texture_cube_map 874 ? ctx->Const.MaxCubeTextureLevels : 0; 875 case GL_TEXTURE_RECTANGLE_NV: 876 case GL_PROXY_TEXTURE_RECTANGLE_NV: 877 return ctx->Extensions.NV_texture_rectangle ? 1 : 0; 878 case GL_TEXTURE_1D_ARRAY_EXT: 879 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 880 case GL_TEXTURE_2D_ARRAY_EXT: 881 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 882 return ctx->Extensions.MESA_texture_array 883 ? ctx->Const.MaxTextureLevels : 0; 884 default: 885 return 0; /* bad target */ 886 } 887} 888 889 890 891#if 000 /* not used anymore */ 892/* 893 * glTexImage[123]D can accept a NULL image pointer. In this case we 894 * create a texture image with unspecified image contents per the OpenGL 895 * spec. 896 */ 897static GLubyte * 898make_null_texture(GLint width, GLint height, GLint depth, GLenum format) 899{ 900 const GLint components = _mesa_components_in_format(format); 901 const GLint numPixels = width * height * depth; 902 GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte)); 903 904#ifdef DEBUG 905 /* 906 * Let's see if anyone finds this. If glTexImage2D() is called with 907 * a NULL image pointer then load the texture image with something 908 * interesting instead of leaving it indeterminate. 909 */ 910 if (data) { 911 static const char message[8][32] = { 912 " X X XXXXX XXX X ", 913 " XX XX X X X X X ", 914 " X X X X X X X ", 915 " X X XXXX XXX XXXXX ", 916 " X X X X X X ", 917 " X X X X X X X ", 918 " X X XXXXX XXX X X ", 919 " " 920 }; 921 922 GLubyte *imgPtr = data; 923 GLint h, i, j, k; 924 for (h = 0; h < depth; h++) { 925 for (i = 0; i < height; i++) { 926 GLint srcRow = 7 - (i % 8); 927 for (j = 0; j < width; j++) { 928 GLint srcCol = j % 32; 929 GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70; 930 for (k = 0; k < components; k++) { 931 *imgPtr++ = texel; 932 } 933 } 934 } 935 } 936 } 937#endif 938 939 return data; 940} 941#endif 942 943 944 945/** 946 * Reset the fields of a gl_texture_image struct to zero. 947 * 948 * \param img texture image structure. 949 * 950 * This is called when a proxy texture test fails, we set all the 951 * image members (except DriverData) to zero. 952 * It's also used in glTexImage[123]D as a safeguard to be sure all 953 * required fields get initialized properly by the Driver.TexImage[123]D 954 * functions. 955 */ 956static void 957clear_teximage_fields(struct gl_texture_image *img) 958{ 959 ASSERT(img); 960 img->_BaseFormat = 0; 961 img->InternalFormat = 0; 962 img->Border = 0; 963 img->Width = 0; 964 img->Height = 0; 965 img->Depth = 0; 966 img->RowStride = 0; 967 if (img->ImageOffsets) { 968 free(img->ImageOffsets); 969 img->ImageOffsets = NULL; 970 } 971 img->Width2 = 0; 972 img->Height2 = 0; 973 img->Depth2 = 0; 974 img->WidthLog2 = 0; 975 img->HeightLog2 = 0; 976 img->DepthLog2 = 0; 977 img->Data = NULL; 978 img->TexFormat = MESA_FORMAT_NONE; 979 img->FetchTexelc = NULL; 980 img->FetchTexelf = NULL; 981} 982 983 984/** 985 * Initialize basic fields of the gl_texture_image struct. 986 * 987 * \param ctx GL context. 988 * \param target texture target (GL_TEXTURE_1D, GL_TEXTURE_RECTANGLE, etc). 989 * \param img texture image structure to be initialized. 990 * \param width image width. 991 * \param height image height. 992 * \param depth image depth. 993 * \param border image border. 994 * \param internalFormat internal format. 995 * 996 * Fills in the fields of \p img with the given information. 997 * Note: width, height and depth include the border. 998 */ 999void 1000_mesa_init_teximage_fields(struct gl_context *ctx, GLenum target, 1001 struct gl_texture_image *img, 1002 GLsizei width, GLsizei height, GLsizei depth, 1003 GLint border, GLenum internalFormat) 1004{ 1005 GLint i; 1006 1007 ASSERT(img); 1008 ASSERT(width >= 0); 1009 ASSERT(height >= 0); 1010 ASSERT(depth >= 0); 1011 1012 img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat ); 1013 ASSERT(img->_BaseFormat > 0); 1014 img->InternalFormat = internalFormat; 1015 img->Border = border; 1016 img->Width = width; 1017 img->Height = height; 1018 img->Depth = depth; 1019 1020 img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */ 1021 img->WidthLog2 = logbase2(img->Width2); 1022 1023 if (height == 1) { /* 1-D texture */ 1024 img->Height2 = 1; 1025 img->HeightLog2 = 0; 1026 } 1027 else { 1028 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 1029 img->HeightLog2 = logbase2(img->Height2); 1030 } 1031 1032 if (depth == 1) { /* 2-D texture */ 1033 img->Depth2 = 1; 1034 img->DepthLog2 = 0; 1035 } 1036 else { 1037 img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */ 1038 img->DepthLog2 = logbase2(img->Depth2); 1039 } 1040 1041 img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); 1042 1043 if ((width == 1 || _mesa_is_pow_two(img->Width2)) && 1044 (height == 1 || _mesa_is_pow_two(img->Height2)) && 1045 (depth == 1 || _mesa_is_pow_two(img->Depth2))) 1046 img->_IsPowerOfTwo = GL_TRUE; 1047 else 1048 img->_IsPowerOfTwo = GL_FALSE; 1049 1050 /* RowStride and ImageOffsets[] describe how to address texels in 'Data' */ 1051 img->RowStride = width; 1052 /* Allocate the ImageOffsets array and initialize to typical values. 1053 * We allocate the array for 1D/2D textures too in order to avoid special- 1054 * case code in the texstore routines. 1055 */ 1056 if (img->ImageOffsets) 1057 free(img->ImageOffsets); 1058 img->ImageOffsets = (GLuint *) malloc(depth * sizeof(GLuint)); 1059 for (i = 0; i < depth; i++) { 1060 img->ImageOffsets[i] = i * width * height; 1061 } 1062 1063 /* Compute Width/Height/DepthScale for mipmap lod computation */ 1064 if (target == GL_TEXTURE_RECTANGLE_NV) { 1065 /* scale = 1.0 since texture coords directly map to texels */ 1066 img->WidthScale = 1.0; 1067 img->HeightScale = 1.0; 1068 img->DepthScale = 1.0; 1069 } 1070 else { 1071 img->WidthScale = (GLfloat) img->Width; 1072 img->HeightScale = (GLfloat) img->Height; 1073 img->DepthScale = (GLfloat) img->Depth; 1074 } 1075 1076 img->FetchTexelc = NULL; 1077 img->FetchTexelf = NULL; 1078} 1079 1080 1081/** 1082 * Free and clear fields of the gl_texture_image struct. 1083 * 1084 * \param ctx GL context. 1085 * \param texImage texture image structure to be cleared. 1086 * 1087 * After the call, \p texImage will have no data associated with it. Its 1088 * fields are cleared so that its parent object will test incomplete. 1089 */ 1090void 1091_mesa_clear_texture_image(struct gl_context *ctx, 1092 struct gl_texture_image *texImage) 1093{ 1094 ctx->Driver.FreeTexImageData(ctx, texImage); 1095 clear_teximage_fields(texImage); 1096} 1097 1098 1099/** 1100 * This is the fallback for Driver.TestProxyTexImage(). Test the texture 1101 * level, width, height and depth against the ctx->Const limits for textures. 1102 * 1103 * A hardware driver might override this function if, for example, the 1104 * max 3D texture size is 512x512x64 (i.e. not a cube). 1105 * 1106 * Note that width, height, depth == 0 is not an error. However, a 1107 * texture with zero width/height/depth will be considered "incomplete" 1108 * and texturing will effectively be disabled. 1109 * 1110 * \param target one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D, 1111 * GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV, 1112 * GL_PROXY_TEXTURE_CUBE_MAP_ARB. 1113 * \param level as passed to glTexImage 1114 * \param internalFormat as passed to glTexImage 1115 * \param format as passed to glTexImage 1116 * \param type as passed to glTexImage 1117 * \param width as passed to glTexImage 1118 * \param height as passed to glTexImage 1119 * \param depth as passed to glTexImage 1120 * \param border as passed to glTexImage 1121 * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable. 1122 */ 1123GLboolean 1124_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level, 1125 GLint internalFormat, GLenum format, GLenum type, 1126 GLint width, GLint height, GLint depth, GLint border) 1127{ 1128 GLint maxSize; 1129 1130 (void) internalFormat; 1131 (void) format; 1132 (void) type; 1133 1134 switch (target) { 1135 case GL_PROXY_TEXTURE_1D: 1136 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1137 if (width < 2 * border || width > 2 + maxSize || 1138 (!ctx->Extensions.ARB_texture_non_power_of_two && 1139 width >0 && !_mesa_is_pow_two(width - 2 * border)) || 1140 level >= ctx->Const.MaxTextureLevels) { 1141 /* bad width or level */ 1142 return GL_FALSE; 1143 } 1144 return GL_TRUE; 1145 case GL_PROXY_TEXTURE_2D: 1146 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1147 if (width < 2 * border || width > 2 + maxSize || 1148 (!ctx->Extensions.ARB_texture_non_power_of_two && 1149 width > 0 && !_mesa_is_pow_two(width - 2 * border)) || 1150 height < 2 * border || height > 2 + maxSize || 1151 (!ctx->Extensions.ARB_texture_non_power_of_two && 1152 height > 0 && !_mesa_is_pow_two(height - 2 * border)) || 1153 level >= ctx->Const.MaxTextureLevels) { 1154 /* bad width or height or level */ 1155 return GL_FALSE; 1156 } 1157 return GL_TRUE; 1158 case GL_PROXY_TEXTURE_3D: 1159 maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); 1160 if (width < 2 * border || width > 2 + maxSize || 1161 (!ctx->Extensions.ARB_texture_non_power_of_two && 1162 width > 0 && !_mesa_is_pow_two(width - 2 * border)) || 1163 height < 2 * border || height > 2 + maxSize || 1164 (!ctx->Extensions.ARB_texture_non_power_of_two && 1165 height > 0 && !_mesa_is_pow_two(height - 2 * border)) || 1166 depth < 2 * border || depth > 2 + maxSize || 1167 (!ctx->Extensions.ARB_texture_non_power_of_two && 1168 depth > 0 && !_mesa_is_pow_two(depth - 2 * border)) || 1169 level >= ctx->Const.Max3DTextureLevels) { 1170 /* bad width or height or depth or level */ 1171 return GL_FALSE; 1172 } 1173 return GL_TRUE; 1174 case GL_PROXY_TEXTURE_RECTANGLE_NV: 1175 if (width < 0 || width > ctx->Const.MaxTextureRectSize || 1176 height < 0 || height > ctx->Const.MaxTextureRectSize || 1177 level != 0) { 1178 /* bad width or height or level */ 1179 return GL_FALSE; 1180 } 1181 return GL_TRUE; 1182 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 1183 maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1); 1184 if (width < 2 * border || width > 2 + maxSize || 1185 (!ctx->Extensions.ARB_texture_non_power_of_two && 1186 width > 0 && !_mesa_is_pow_two(width - 2 * border)) || 1187 height < 2 * border || height > 2 + maxSize || 1188 (!ctx->Extensions.ARB_texture_non_power_of_two && 1189 height > 0 && !_mesa_is_pow_two(height - 2 * border)) || 1190 level >= ctx->Const.MaxCubeTextureLevels) { 1191 /* bad width or height */ 1192 return GL_FALSE; 1193 } 1194 return GL_TRUE; 1195 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 1196 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1197 if (width < 2 * border || width > 2 + maxSize || 1198 (!ctx->Extensions.ARB_texture_non_power_of_two && 1199 width > 0 && !_mesa_is_pow_two(width - 2 * border)) || 1200 level >= ctx->Const.MaxTextureLevels) { 1201 /* bad width or level */ 1202 return GL_FALSE; 1203 } 1204 1205 if (height < 1 || height > ctx->Const.MaxArrayTextureLayers) { 1206 return GL_FALSE; 1207 } 1208 return GL_TRUE; 1209 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1210 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1211 if (width < 2 * border || width > 2 + maxSize || 1212 (!ctx->Extensions.ARB_texture_non_power_of_two && 1213 width > 0 && !_mesa_is_pow_two(width - 2 * border)) || 1214 height < 2 * border || height > 2 + maxSize || 1215 (!ctx->Extensions.ARB_texture_non_power_of_two && 1216 height > 0 && !_mesa_is_pow_two(height - 2 * border)) || 1217 level >= ctx->Const.MaxTextureLevels) { 1218 /* bad width or height or level */ 1219 return GL_FALSE; 1220 } 1221 if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers) { 1222 return GL_FALSE; 1223 } 1224 return GL_TRUE; 1225 default: 1226 _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage"); 1227 return GL_FALSE; 1228 } 1229} 1230 1231 1232/** 1233 * Helper function to determine whether a target supports compressed textures 1234 */ 1235static GLboolean 1236target_can_be_compressed(struct gl_context *ctx, GLenum target) 1237{ 1238 switch (target) { 1239 case GL_TEXTURE_2D: 1240 case GL_PROXY_TEXTURE_2D: 1241 return GL_TRUE; 1242 case GL_PROXY_TEXTURE_CUBE_MAP: 1243 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1244 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1245 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1246 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1247 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1248 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1249 return ctx->Extensions.ARB_texture_cube_map; 1250 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1251 case GL_TEXTURE_2D_ARRAY_EXT: 1252 return ctx->Extensions.MESA_texture_array; 1253 default: 1254 return GL_FALSE; 1255 } 1256} 1257 1258 1259/** 1260 * Test the glTexImage[123]D() parameters for errors. 1261 * 1262 * \param ctx GL context. 1263 * \param target texture target given by the user. 1264 * \param level image level given by the user. 1265 * \param internalFormat internal format given by the user. 1266 * \param format pixel data format given by the user. 1267 * \param type pixel data type given by the user. 1268 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1269 * \param width image width given by the user. 1270 * \param height image height given by the user. 1271 * \param depth image depth given by the user. 1272 * \param border image border given by the user. 1273 * 1274 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 1275 * 1276 * Verifies each of the parameters against the constants specified in 1277 * __struct gl_contextRec::Const and the supported extensions, and according 1278 * to the OpenGL specification. 1279 */ 1280static GLboolean 1281texture_error_check( struct gl_context *ctx, GLenum target, 1282 GLint level, GLint internalFormat, 1283 GLenum format, GLenum type, 1284 GLuint dimensions, 1285 GLint width, GLint height, 1286 GLint depth, GLint border ) 1287{ 1288 const GLboolean isProxy = _mesa_is_proxy_texture(target); 1289 GLboolean sizeOK = GL_TRUE; 1290 GLboolean colorFormat, indexFormat; 1291 GLenum proxy_target; 1292 1293 /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */ 1294 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 1295 if (!isProxy) { 1296 _mesa_error(ctx, GL_INVALID_VALUE, 1297 "glTexImage%dD(level=%d)", dimensions, level); 1298 } 1299 return GL_TRUE; 1300 } 1301 1302 /* Check border */ 1303 if (border < 0 || border > 1 || 1304 ((target == GL_TEXTURE_RECTANGLE_NV || 1305 target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { 1306 if (!isProxy) { 1307 _mesa_error(ctx, GL_INVALID_VALUE, 1308 "glTexImage%dD(border=%d)", dimensions, border); 1309 } 1310 return GL_TRUE; 1311 } 1312 1313 if (width < 0 || height < 0 || depth < 0) { 1314 if (!isProxy) { 1315 _mesa_error(ctx, GL_INVALID_VALUE, 1316 "glTexImage%dD(width, height or depth < 0)", dimensions); 1317 } 1318 return GL_TRUE; 1319 } 1320 1321 /* Check target and call ctx->Driver.TestProxyTexImage() to check the 1322 * level, width, height and depth. 1323 */ 1324 if (dimensions == 1) { 1325 if (target == GL_PROXY_TEXTURE_1D || target == GL_TEXTURE_1D) { 1326 proxy_target = GL_PROXY_TEXTURE_1D; 1327 height = 1; 1328 depth = 1; 1329 } 1330 else { 1331 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" ); 1332 return GL_TRUE; 1333 } 1334 } 1335 else if (dimensions == 2) { 1336 depth = 1; 1337 if (target == GL_PROXY_TEXTURE_2D || target == GL_TEXTURE_2D) { 1338 proxy_target = GL_PROXY_TEXTURE_2D; 1339 } 1340 else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB || 1341 (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 1342 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { 1343 if (!ctx->Extensions.ARB_texture_cube_map) { 1344 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); 1345 return GL_TRUE; 1346 } 1347 proxy_target = GL_PROXY_TEXTURE_CUBE_MAP_ARB; 1348 sizeOK = (width == height); 1349 } 1350 else if (target == GL_PROXY_TEXTURE_RECTANGLE_NV || 1351 target == GL_TEXTURE_RECTANGLE_NV) { 1352 if (!ctx->Extensions.NV_texture_rectangle) { 1353 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); 1354 return GL_TRUE; 1355 } 1356 proxy_target = GL_PROXY_TEXTURE_RECTANGLE_NV; 1357 } 1358 else if (target == GL_PROXY_TEXTURE_1D_ARRAY_EXT || 1359 target == GL_TEXTURE_1D_ARRAY_EXT) { 1360 proxy_target = GL_PROXY_TEXTURE_1D_ARRAY_EXT; 1361 } 1362 else { 1363 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); 1364 return GL_TRUE; 1365 } 1366 } 1367 else if (dimensions == 3) { 1368 if (target == GL_PROXY_TEXTURE_3D || target == GL_TEXTURE_3D) { 1369 proxy_target = GL_PROXY_TEXTURE_3D; 1370 } 1371 else if (target == GL_PROXY_TEXTURE_2D_ARRAY_EXT || 1372 target == GL_TEXTURE_2D_ARRAY_EXT) { 1373 proxy_target = GL_PROXY_TEXTURE_2D_ARRAY_EXT; 1374 } 1375 else { 1376 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" ); 1377 return GL_TRUE; 1378 } 1379 } 1380 else { 1381 _mesa_problem( ctx, "bad dims in texture_error_check" ); 1382 return GL_TRUE; 1383 } 1384 1385 sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxy_target, level, 1386 internalFormat, format, 1387 type, width, height, 1388 depth, border); 1389 if (!sizeOK) { 1390 if (!isProxy) { 1391 _mesa_error(ctx, GL_INVALID_VALUE, 1392 "glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)", 1393 dimensions, level, width, height, depth); 1394 } 1395 return GL_TRUE; 1396 } 1397 1398 /* Check internalFormat */ 1399 if (_mesa_base_tex_format(ctx, internalFormat) < 0) { 1400 if (!isProxy) { 1401 _mesa_error(ctx, GL_INVALID_VALUE, 1402 "glTexImage%dD(internalFormat=%s)", 1403 dimensions, _mesa_lookup_enum_by_nr(internalFormat)); 1404 } 1405 return GL_TRUE; 1406 } 1407 1408 /* Check incoming image format and type */ 1409 if (!_mesa_is_legal_format_and_type(ctx, format, type)) { 1410 /* Normally, GL_INVALID_OPERATION is generated by a format/type 1411 * mismatch (see the 1.2 spec page 94, sec 3.6.4.). But with the 1412 * GL_EXT_texture_integer extension, some combinations should generate 1413 * GL_INVALID_ENUM instead (grr!). 1414 */ 1415 if (!isProxy) { 1416 GLenum error = _mesa_is_integer_format(format) 1417 ? GL_INVALID_ENUM : GL_INVALID_OPERATION; 1418 _mesa_error(ctx, error, 1419 "glTexImage%dD(incompatible format 0x%x, type 0x%x)", 1420 dimensions, format, type); 1421 } 1422 return GL_TRUE; 1423 } 1424 1425 /* make sure internal format and format basically agree */ 1426 colorFormat = _mesa_is_color_format(format); 1427 indexFormat = _mesa_is_index_format(format); 1428 if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) || 1429 (_mesa_is_index_format(internalFormat) && !indexFormat) || 1430 (_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) || 1431 (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) || 1432 (_mesa_is_depthstencil_format(internalFormat) != _mesa_is_depthstencil_format(format)) || 1433 (_mesa_is_dudv_format(internalFormat) != _mesa_is_dudv_format(format))) { 1434 if (!isProxy) 1435 _mesa_error(ctx, GL_INVALID_OPERATION, 1436 "glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)", 1437 dimensions, internalFormat, format); 1438 return GL_TRUE; 1439 } 1440 1441 /* additional checks for ycbcr textures */ 1442 if (internalFormat == GL_YCBCR_MESA) { 1443 ASSERT(ctx->Extensions.MESA_ycbcr_texture); 1444 if (type != GL_UNSIGNED_SHORT_8_8_MESA && 1445 type != GL_UNSIGNED_SHORT_8_8_REV_MESA) { 1446 char message[100]; 1447 _mesa_snprintf(message, sizeof(message), 1448 "glTexImage%dD(format/type YCBCR mismatch", dimensions); 1449 _mesa_error(ctx, GL_INVALID_ENUM, "%s", message); 1450 return GL_TRUE; /* error */ 1451 } 1452 if (target != GL_TEXTURE_2D && 1453 target != GL_PROXY_TEXTURE_2D && 1454 target != GL_TEXTURE_RECTANGLE_NV && 1455 target != GL_PROXY_TEXTURE_RECTANGLE_NV) { 1456 if (!isProxy) 1457 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage(target)"); 1458 return GL_TRUE; 1459 } 1460 if (border != 0) { 1461 if (!isProxy) { 1462 char message[100]; 1463 _mesa_snprintf(message, sizeof(message), 1464 "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)", 1465 dimensions, border); 1466 _mesa_error(ctx, GL_INVALID_VALUE, "%s", message); 1467 } 1468 return GL_TRUE; 1469 } 1470 } 1471 1472 /* additional checks for depth textures */ 1473 if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) { 1474 /* Only 1D, 2D and rectangular textures supported, not 3D or cubes */ 1475 if (target != GL_TEXTURE_1D && 1476 target != GL_PROXY_TEXTURE_1D && 1477 target != GL_TEXTURE_2D && 1478 target != GL_PROXY_TEXTURE_2D && 1479 target != GL_TEXTURE_RECTANGLE_ARB && 1480 target != GL_PROXY_TEXTURE_RECTANGLE_ARB) { 1481 if (!isProxy) 1482 _mesa_error(ctx, GL_INVALID_ENUM, 1483 "glTexImage(target/internalFormat)"); 1484 return GL_TRUE; 1485 } 1486 } 1487 1488 /* additional checks for compressed textures */ 1489 if (_mesa_is_compressed_format(ctx, internalFormat)) { 1490 if (!target_can_be_compressed(ctx, target) && !isProxy) { 1491 _mesa_error(ctx, GL_INVALID_ENUM, 1492 "glTexImage%dD(target)", dimensions); 1493 return GL_TRUE; 1494 } 1495 if (border != 0) { 1496 if (!isProxy) { 1497 _mesa_error(ctx, GL_INVALID_OPERATION, 1498 "glTexImage%dD(border!=0)", dimensions); 1499 } 1500 return GL_TRUE; 1501 } 1502 } 1503 1504 /* additional checks for integer textures */ 1505 if (ctx->Extensions.EXT_texture_integer && 1506 (_mesa_is_integer_format(format) != 1507 _mesa_is_integer_format(internalFormat))) { 1508 if (!isProxy) { 1509 _mesa_error(ctx, GL_INVALID_OPERATION, 1510 "glTexImage%dD(integer/non-integer format mismatch)", 1511 dimensions); 1512 } 1513 return GL_TRUE; 1514 } 1515 1516 /* if we get here, the parameters are OK */ 1517 return GL_FALSE; 1518} 1519 1520 1521/** 1522 * Test glTexSubImage[123]D() parameters for errors. 1523 * 1524 * \param ctx GL context. 1525 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1526 * \param target texture target given by the user. 1527 * \param level image level given by the user. 1528 * \param xoffset sub-image x offset given by the user. 1529 * \param yoffset sub-image y offset given by the user. 1530 * \param zoffset sub-image z offset given by the user. 1531 * \param format pixel data format given by the user. 1532 * \param type pixel data type given by the user. 1533 * \param width image width given by the user. 1534 * \param height image height given by the user. 1535 * \param depth image depth given by the user. 1536 * 1537 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 1538 * 1539 * Verifies each of the parameters against the constants specified in 1540 * __struct gl_contextRec::Const and the supported extensions, and according 1541 * to the OpenGL specification. 1542 */ 1543static GLboolean 1544subtexture_error_check( struct gl_context *ctx, GLuint dimensions, 1545 GLenum target, GLint level, 1546 GLint xoffset, GLint yoffset, GLint zoffset, 1547 GLint width, GLint height, GLint depth, 1548 GLenum format, GLenum type ) 1549{ 1550 /* Check target */ 1551 if (dimensions == 1) { 1552 if (target != GL_TEXTURE_1D) { 1553 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" ); 1554 return GL_TRUE; 1555 } 1556 } 1557 else if (dimensions == 2) { 1558 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 1559 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 1560 if (!ctx->Extensions.ARB_texture_cube_map) { 1561 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); 1562 return GL_TRUE; 1563 } 1564 } 1565 else if (target == GL_TEXTURE_RECTANGLE_NV) { 1566 if (!ctx->Extensions.NV_texture_rectangle) { 1567 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); 1568 return GL_TRUE; 1569 } 1570 } 1571 else if (target == GL_TEXTURE_1D_ARRAY_EXT) { 1572 if (!ctx->Extensions.MESA_texture_array) { 1573 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); 1574 return GL_TRUE; 1575 } 1576 } 1577 else if (target != GL_TEXTURE_2D) { 1578 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); 1579 return GL_TRUE; 1580 } 1581 } 1582 else if (dimensions == 3) { 1583 if (target == GL_TEXTURE_2D_ARRAY_EXT) { 1584 if (!ctx->Extensions.MESA_texture_array) { 1585 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" ); 1586 return GL_TRUE; 1587 } 1588 } 1589 else if (target != GL_TEXTURE_3D) { 1590 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" ); 1591 return GL_TRUE; 1592 } 1593 } 1594 else { 1595 _mesa_problem( ctx, "invalid dims in texture_error_check" ); 1596 return GL_TRUE; 1597 } 1598 1599 /* Basic level check */ 1600 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 1601 _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level); 1602 return GL_TRUE; 1603 } 1604 1605 if (width < 0) { 1606 _mesa_error(ctx, GL_INVALID_VALUE, 1607 "glTexSubImage%dD(width=%d)", dimensions, width); 1608 return GL_TRUE; 1609 } 1610 if (height < 0 && dimensions > 1) { 1611 _mesa_error(ctx, GL_INVALID_VALUE, 1612 "glTexSubImage%dD(height=%d)", dimensions, height); 1613 return GL_TRUE; 1614 } 1615 if (depth < 0 && dimensions > 2) { 1616 _mesa_error(ctx, GL_INVALID_VALUE, 1617 "glTexSubImage%dD(depth=%d)", dimensions, depth); 1618 return GL_TRUE; 1619 } 1620 1621 if (!_mesa_is_legal_format_and_type(ctx, format, type)) { 1622 /* As with the glTexImage2D check above, the error code here 1623 * depends on texture integer. 1624 */ 1625 GLenum error = _mesa_is_integer_format(format) 1626 ? GL_INVALID_OPERATION : GL_INVALID_ENUM; 1627 _mesa_error(ctx, error, 1628 "glTexSubImage%dD(incompatible format 0x%x, type 0x%x)", 1629 dimensions, format, type); 1630 return GL_TRUE; 1631 } 1632 1633 return GL_FALSE; 1634} 1635 1636 1637/** 1638 * Do second part of glTexSubImage which depends on the destination texture. 1639 * \return GL_TRUE if error recorded, GL_FALSE otherwise 1640 */ 1641static GLboolean 1642subtexture_error_check2( struct gl_context *ctx, GLuint dimensions, 1643 GLenum target, GLint level, 1644 GLint xoffset, GLint yoffset, GLint zoffset, 1645 GLint width, GLint height, GLint depth, 1646 GLenum format, GLenum type, 1647 const struct gl_texture_image *destTex ) 1648{ 1649 if (!destTex) { 1650 /* undefined image level */ 1651 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions); 1652 return GL_TRUE; 1653 } 1654 1655 if (xoffset < -((GLint)destTex->Border)) { 1656 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)", 1657 dimensions); 1658 return GL_TRUE; 1659 } 1660 if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) { 1661 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)", 1662 dimensions); 1663 return GL_TRUE; 1664 } 1665 if (dimensions > 1) { 1666 if (yoffset < -((GLint)destTex->Border)) { 1667 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)", 1668 dimensions); 1669 return GL_TRUE; 1670 } 1671 if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) { 1672 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)", 1673 dimensions); 1674 return GL_TRUE; 1675 } 1676 } 1677 if (dimensions > 2) { 1678 if (zoffset < -((GLint)destTex->Border)) { 1679 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)"); 1680 return GL_TRUE; 1681 } 1682 if (zoffset + depth > (GLint) (destTex->Depth + destTex->Border)) { 1683 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)"); 1684 return GL_TRUE; 1685 } 1686 } 1687 1688 if (_mesa_is_format_compressed(destTex->TexFormat)) { 1689 GLuint bw, bh; 1690 1691 if (!target_can_be_compressed(ctx, target)) { 1692 _mesa_error(ctx, GL_INVALID_ENUM, 1693 "glTexSubImage%dD(target=%s)", dimensions, 1694 _mesa_lookup_enum_by_nr(target)); 1695 return GL_TRUE; 1696 } 1697 1698 /* do tests which depend on compression block size */ 1699 _mesa_get_format_block_size(destTex->TexFormat, &bw, &bh); 1700 1701 /* offset must be multiple of block size */ 1702 if ((xoffset % bw != 0) || (yoffset % bh != 0)) { 1703 _mesa_error(ctx, GL_INVALID_OPERATION, 1704 "glTexSubImage%dD(xoffset = %d, yoffset = %d)", 1705 dimensions, xoffset, yoffset); 1706 return GL_TRUE; 1707 } 1708 /* size must be multiple of bw by bh or equal to whole texture size */ 1709 if ((width % bw != 0) && (GLuint) width != destTex->Width) { 1710 _mesa_error(ctx, GL_INVALID_OPERATION, 1711 "glTexSubImage%dD(width = %d)", dimensions, width); 1712 return GL_TRUE; 1713 } 1714 if ((height % bh != 0) && (GLuint) height != destTex->Height) { 1715 _mesa_error(ctx, GL_INVALID_OPERATION, 1716 "glTexSubImage%dD(height = %d)", dimensions, height); 1717 return GL_TRUE; 1718 } 1719 } 1720 1721 return GL_FALSE; 1722} 1723 1724 1725/** 1726 * Test glCopyTexImage[12]D() parameters for errors. 1727 * 1728 * \param ctx GL context. 1729 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1730 * \param target texture target given by the user. 1731 * \param level image level given by the user. 1732 * \param internalFormat internal format given by the user. 1733 * \param width image width given by the user. 1734 * \param height image height given by the user. 1735 * \param border texture border. 1736 * 1737 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 1738 * 1739 * Verifies each of the parameters against the constants specified in 1740 * __struct gl_contextRec::Const and the supported extensions, and according 1741 * to the OpenGL specification. 1742 */ 1743static GLboolean 1744copytexture_error_check( struct gl_context *ctx, GLuint dimensions, 1745 GLenum target, GLint level, GLint internalFormat, 1746 GLint width, GLint height, GLint border ) 1747{ 1748 GLenum type; 1749 GLboolean sizeOK; 1750 GLint format; 1751 1752 /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */ 1753 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 1754 _mesa_error(ctx, GL_INVALID_VALUE, 1755 "glCopyTexImage%dD(level=%d)", dimensions, level); 1756 return GL_TRUE; 1757 } 1758 1759 /* Check that the source buffer is complete */ 1760 if (ctx->ReadBuffer->Name) { 1761 _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); 1762 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 1763 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 1764 "glCopyTexImage%dD(invalid readbuffer)", dimensions); 1765 return GL_TRUE; 1766 } 1767 } 1768 1769 /* Check border */ 1770 if (border < 0 || border > 1 || 1771 ((target == GL_TEXTURE_RECTANGLE_NV || 1772 target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { 1773 return GL_TRUE; 1774 } 1775 1776 format = _mesa_base_tex_format(ctx, internalFormat); 1777 if (format < 0) { 1778 _mesa_error(ctx, GL_INVALID_VALUE, 1779 "glCopyTexImage%dD(internalFormat)", dimensions); 1780 return GL_TRUE; 1781 } 1782 1783 if (!_mesa_source_buffer_exists(ctx, format)) { 1784 _mesa_error(ctx, GL_INVALID_OPERATION, 1785 "glCopyTexImage%dD(missing readbuffer)", dimensions); 1786 return GL_TRUE; 1787 } 1788 1789 /* NOTE: the format and type aren't really significant for 1790 * TestProxyTexImage(). Only the internalformat really matters. 1791 */ 1792 type = GL_FLOAT; 1793 1794 /* Check target and call ctx->Driver.TestProxyTexImage() to check the 1795 * level, width, height and depth. 1796 */ 1797 if (dimensions == 1) { 1798 if (target == GL_TEXTURE_1D) { 1799 sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_1D, 1800 level, internalFormat, 1801 format, type, 1802 width, 1, 1, border); 1803 } 1804 else { 1805 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" ); 1806 return GL_TRUE; 1807 } 1808 } 1809 else if (dimensions == 2) { 1810 if (target == GL_TEXTURE_2D) { 1811 sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_2D, 1812 level, internalFormat, 1813 format, type, 1814 width, height, 1, border); 1815 } 1816 else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 1817 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 1818 if (!ctx->Extensions.ARB_texture_cube_map) { 1819 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); 1820 return GL_TRUE; 1821 } 1822 sizeOK = (width == height) && 1823 ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_CUBE_MAP_ARB, 1824 level, internalFormat, format, type, 1825 width, height, 1, border); 1826 } 1827 else if (target == GL_TEXTURE_RECTANGLE_NV) { 1828 if (!ctx->Extensions.NV_texture_rectangle) { 1829 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); 1830 return GL_TRUE; 1831 } 1832 sizeOK = ctx->Driver.TestProxyTexImage(ctx, 1833 GL_PROXY_TEXTURE_RECTANGLE_NV, 1834 level, internalFormat, 1835 format, type, 1836 width, height, 1, border); 1837 } 1838 else if (target == GL_TEXTURE_1D_ARRAY_EXT) { 1839 if (!ctx->Extensions.MESA_texture_array) { 1840 _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)"); 1841 return GL_TRUE; 1842 } 1843 sizeOK = ctx->Driver.TestProxyTexImage(ctx, 1844 GL_PROXY_TEXTURE_1D_ARRAY_EXT, 1845 level, internalFormat, 1846 format, type, 1847 width, height, 1, border); 1848 } 1849 else { 1850 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); 1851 return GL_TRUE; 1852 } 1853 } 1854 else { 1855 _mesa_problem(ctx, "invalid dimensions in copytexture_error_check"); 1856 return GL_TRUE; 1857 } 1858 1859 if (!sizeOK) { 1860 if (dimensions == 1) { 1861 _mesa_error(ctx, GL_INVALID_VALUE, 1862 "glCopyTexImage1D(width=%d)", width); 1863 } 1864 else { 1865 ASSERT(dimensions == 2); 1866 _mesa_error(ctx, GL_INVALID_VALUE, 1867 "glCopyTexImage2D(width=%d, height=%d)", width, height); 1868 } 1869 return GL_TRUE; 1870 } 1871 1872 if (_mesa_is_compressed_format(ctx, internalFormat)) { 1873 if (!target_can_be_compressed(ctx, target)) { 1874 _mesa_error(ctx, GL_INVALID_ENUM, 1875 "glCopyTexImage%dD(target)", dimensions); 1876 return GL_TRUE; 1877 } 1878 if (border != 0) { 1879 _mesa_error(ctx, GL_INVALID_OPERATION, 1880 "glCopyTexImage%dD(border!=0)", dimensions); 1881 return GL_TRUE; 1882 } 1883 } 1884 else if (_mesa_is_depth_format(internalFormat)) { 1885 /* make sure we have depth/stencil buffers */ 1886 if (!ctx->ReadBuffer->_DepthBuffer) { 1887 _mesa_error(ctx, GL_INVALID_OPERATION, 1888 "glCopyTexImage%dD(no depth)", dimensions); 1889 return GL_TRUE; 1890 } 1891 } 1892 else if (_mesa_is_depthstencil_format(internalFormat)) { 1893 /* make sure we have depth/stencil buffers */ 1894 if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) { 1895 _mesa_error(ctx, GL_INVALID_OPERATION, 1896 "glCopyTexImage%dD(no depth/stencil buffer)", dimensions); 1897 return GL_TRUE; 1898 } 1899 } 1900 1901 /* if we get here, the parameters are OK */ 1902 return GL_FALSE; 1903} 1904 1905 1906/** 1907 * Test glCopyTexSubImage[12]D() parameters for errors. 1908 * Note that this is the first part of error checking. 1909 * See also copytexsubimage_error_check2() below for the second part. 1910 * 1911 * \param ctx GL context. 1912 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1913 * \param target texture target given by the user. 1914 * \param level image level given by the user. 1915 * 1916 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 1917 */ 1918static GLboolean 1919copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions, 1920 GLenum target, GLint level) 1921{ 1922 /* Check that the source buffer is complete */ 1923 if (ctx->ReadBuffer->Name) { 1924 _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); 1925 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 1926 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 1927 "glCopyTexImage%dD(invalid readbuffer)", dimensions); 1928 return GL_TRUE; 1929 } 1930 } 1931 1932 /* Check target */ 1933 if (dimensions == 1) { 1934 if (target != GL_TEXTURE_1D) { 1935 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" ); 1936 return GL_TRUE; 1937 } 1938 } 1939 else if (dimensions == 2) { 1940 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 1941 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 1942 if (!ctx->Extensions.ARB_texture_cube_map) { 1943 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); 1944 return GL_TRUE; 1945 } 1946 } 1947 else if (target == GL_TEXTURE_RECTANGLE_NV) { 1948 if (!ctx->Extensions.NV_texture_rectangle) { 1949 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); 1950 return GL_TRUE; 1951 } 1952 } 1953 else if (target == GL_TEXTURE_1D_ARRAY_EXT) { 1954 if (!ctx->Extensions.MESA_texture_array) { 1955 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); 1956 return GL_TRUE; 1957 } 1958 } 1959 else if (target != GL_TEXTURE_2D) { 1960 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); 1961 return GL_TRUE; 1962 } 1963 } 1964 else if (dimensions == 3) { 1965 if (((target != GL_TEXTURE_2D_ARRAY_EXT) || 1966 (!ctx->Extensions.MESA_texture_array)) 1967 && (target != GL_TEXTURE_3D)) { 1968 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" ); 1969 return GL_TRUE; 1970 } 1971 } 1972 1973 /* Check level */ 1974 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 1975 _mesa_error(ctx, GL_INVALID_VALUE, 1976 "glCopyTexSubImage%dD(level=%d)", dimensions, level); 1977 return GL_TRUE; 1978 } 1979 1980 return GL_FALSE; 1981} 1982 1983 1984/** 1985 * Second part of error checking for glCopyTexSubImage[12]D(). 1986 * \param xoffset sub-image x offset given by the user. 1987 * \param yoffset sub-image y offset given by the user. 1988 * \param zoffset sub-image z offset given by the user. 1989 * \param width image width given by the user. 1990 * \param height image height given by the user. 1991 */ 1992static GLboolean 1993copytexsubimage_error_check2( struct gl_context *ctx, GLuint dimensions, 1994 GLenum target, GLint level, 1995 GLint xoffset, GLint yoffset, GLint zoffset, 1996 GLsizei width, GLsizei height, 1997 const struct gl_texture_image *teximage ) 1998{ 1999 /* check that dest tex image exists */ 2000 if (!teximage) { 2001 _mesa_error(ctx, GL_INVALID_OPERATION, 2002 "glCopyTexSubImage%dD(undefined texture level: %d)", 2003 dimensions, level); 2004 return GL_TRUE; 2005 } 2006 2007 /* Check size */ 2008 if (width < 0) { 2009 _mesa_error(ctx, GL_INVALID_VALUE, 2010 "glCopyTexSubImage%dD(width=%d)", dimensions, width); 2011 return GL_TRUE; 2012 } 2013 if (dimensions > 1 && height < 0) { 2014 _mesa_error(ctx, GL_INVALID_VALUE, 2015 "glCopyTexSubImage%dD(height=%d)", dimensions, height); 2016 return GL_TRUE; 2017 } 2018 2019 /* check x/y offsets */ 2020 if (xoffset < -((GLint)teximage->Border)) { 2021 _mesa_error(ctx, GL_INVALID_VALUE, 2022 "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset); 2023 return GL_TRUE; 2024 } 2025 if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) { 2026 _mesa_error(ctx, GL_INVALID_VALUE, 2027 "glCopyTexSubImage%dD(xoffset+width)", dimensions); 2028 return GL_TRUE; 2029 } 2030 if (dimensions > 1) { 2031 if (yoffset < -((GLint)teximage->Border)) { 2032 _mesa_error(ctx, GL_INVALID_VALUE, 2033 "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset); 2034 return GL_TRUE; 2035 } 2036 /* NOTE: we're adding the border here, not subtracting! */ 2037 if (yoffset + height > (GLint) (teximage->Height + teximage->Border)) { 2038 _mesa_error(ctx, GL_INVALID_VALUE, 2039 "glCopyTexSubImage%dD(yoffset+height)", dimensions); 2040 return GL_TRUE; 2041 } 2042 } 2043 2044 /* check z offset */ 2045 if (dimensions > 2) { 2046 if (zoffset < -((GLint)teximage->Border)) { 2047 _mesa_error(ctx, GL_INVALID_VALUE, 2048 "glCopyTexSubImage%dD(zoffset)", dimensions); 2049 return GL_TRUE; 2050 } 2051 if (zoffset > (GLint) (teximage->Depth + teximage->Border)) { 2052 _mesa_error(ctx, GL_INVALID_VALUE, 2053 "glCopyTexSubImage%dD(zoffset+depth)", dimensions); 2054 return GL_TRUE; 2055 } 2056 } 2057 2058 if (_mesa_is_format_compressed(teximage->TexFormat)) { 2059 if (!target_can_be_compressed(ctx, target)) { 2060 _mesa_error(ctx, GL_INVALID_ENUM, 2061 "glCopyTexSubImage%dD(target)", dimensions); 2062 return GL_TRUE; 2063 } 2064 /* offset must be multiple of 4 */ 2065 if ((xoffset & 3) || (yoffset & 3)) { 2066 _mesa_error(ctx, GL_INVALID_VALUE, 2067 "glCopyTexSubImage%dD(xoffset or yoffset)", dimensions); 2068 return GL_TRUE; 2069 } 2070 /* size must be multiple of 4 */ 2071 if ((width & 3) != 0 && (GLuint) width != teximage->Width) { 2072 _mesa_error(ctx, GL_INVALID_VALUE, 2073 "glCopyTexSubImage%dD(width)", dimensions); 2074 return GL_TRUE; 2075 } 2076 if ((height & 3) != 0 && (GLuint) height != teximage->Height) { 2077 _mesa_error(ctx, GL_INVALID_VALUE, 2078 "glCopyTexSubImage%dD(height)", dimensions); 2079 return GL_TRUE; 2080 } 2081 } 2082 2083 if (teximage->InternalFormat == GL_YCBCR_MESA) { 2084 _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D"); 2085 return GL_TRUE; 2086 } 2087 2088 if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) { 2089 _mesa_error(ctx, GL_INVALID_OPERATION, 2090 "glCopyTexSubImage%dD(missing readbuffer, format=0x%x)", 2091 dimensions, teximage->_BaseFormat); 2092 return GL_TRUE; 2093 } 2094 2095 if (teximage->_BaseFormat == GL_DEPTH_COMPONENT) { 2096 if (!ctx->ReadBuffer->_DepthBuffer) { 2097 _mesa_error(ctx, GL_INVALID_OPERATION, 2098 "glCopyTexSubImage%dD(no depth buffer)", 2099 dimensions); 2100 return GL_TRUE; 2101 } 2102 } 2103 else if (teximage->_BaseFormat == GL_DEPTH_STENCIL_EXT) { 2104 if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) { 2105 _mesa_error(ctx, GL_INVALID_OPERATION, 2106 "glCopyTexSubImage%dD(no depth/stencil buffer)", 2107 dimensions); 2108 return GL_TRUE; 2109 } 2110 } 2111 2112 /* If copying into an integer texture, the source buffer must also be 2113 * integer-valued. 2114 */ 2115 if (_mesa_is_format_integer_color(teximage->TexFormat)) { 2116 struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; 2117 if (!_mesa_is_format_integer_color(rb->Format)) { 2118 _mesa_error(ctx, GL_INVALID_OPERATION, 2119 "glCopyTexSubImage%dD(source buffer is not integer format)", 2120 dimensions); 2121 return GL_TRUE; 2122 } 2123 } 2124 2125 /* if we get here, the parameters are OK */ 2126 return GL_FALSE; 2127} 2128 2129 2130/** Callback info for walking over FBO hash table */ 2131struct cb_info 2132{ 2133 struct gl_context *ctx; 2134 struct gl_texture_object *texObj; 2135 GLuint level, face; 2136}; 2137 2138 2139/** 2140 * Check render to texture callback. Called from _mesa_HashWalk(). 2141 */ 2142static void 2143check_rtt_cb(GLuint key, void *data, void *userData) 2144{ 2145 struct gl_framebuffer *fb = (struct gl_framebuffer *) data; 2146 const struct cb_info *info = (struct cb_info *) userData; 2147 struct gl_context *ctx = info->ctx; 2148 const struct gl_texture_object *texObj = info->texObj; 2149 const GLuint level = info->level, face = info->face; 2150 2151 /* If this is a user-created FBO */ 2152 if (fb->Name) { 2153 GLuint i; 2154 /* check if any of the FBO's attachments point to 'texObj' */ 2155 for (i = 0; i < BUFFER_COUNT; i++) { 2156 struct gl_renderbuffer_attachment *att = fb->Attachment + i; 2157 if (att->Type == GL_TEXTURE && 2158 att->Texture == texObj && 2159 att->TextureLevel == level && 2160 att->CubeMapFace == face) { 2161 ASSERT(att->Texture->Image[att->CubeMapFace][att->TextureLevel]); 2162 /* Tell driver about the new renderbuffer texture */ 2163 ctx->Driver.RenderTexture(ctx, ctx->DrawBuffer, att); 2164 /* Mark fb status as indeterminate to force re-validation */ 2165 fb->_Status = 0; 2166 } 2167 } 2168 } 2169} 2170 2171 2172/** 2173 * When a texture image is specified we have to check if it's bound to 2174 * any framebuffer objects (render to texture) in order to detect changes 2175 * in size or format since that effects FBO completeness. 2176 * Any FBOs rendering into the texture must be re-validated. 2177 */ 2178static void 2179update_fbo_texture(struct gl_context *ctx, struct gl_texture_object *texObj, 2180 GLuint face, GLuint level) 2181{ 2182 /* Only check this texture if it's been marked as RenderToTexture */ 2183 if (texObj->_RenderToTexture) { 2184 struct cb_info info; 2185 info.ctx = ctx; 2186 info.texObj = texObj; 2187 info.level = level; 2188 info.face = face; 2189 _mesa_HashWalk(ctx->Shared->FrameBuffers, check_rtt_cb, &info); 2190 } 2191} 2192 2193 2194/** 2195 * If the texture object's GenerateMipmap flag is set and we've 2196 * changed the texture base level image, regenerate the rest of the 2197 * mipmap levels now. 2198 */ 2199static INLINE void 2200check_gen_mipmap(struct gl_context *ctx, GLenum target, 2201 struct gl_texture_object *texObj, GLint level) 2202{ 2203 ASSERT(target != GL_TEXTURE_CUBE_MAP); 2204 if (texObj->GenerateMipmap && 2205 level == texObj->BaseLevel && 2206 level < texObj->MaxLevel) { 2207 ASSERT(ctx->Driver.GenerateMipmap); 2208 ctx->Driver.GenerateMipmap(ctx, target, texObj); 2209 } 2210} 2211 2212 2213/** Debug helper: override the user-requested internal format */ 2214static GLenum 2215override_internal_format(GLenum internalFormat, GLint width, GLint height) 2216{ 2217#if 0 2218 if (internalFormat == GL_RGBA16F_ARB || 2219 internalFormat == GL_RGBA32F_ARB) { 2220 printf("Convert rgba float tex to int %d x %d\n", width, height); 2221 return GL_RGBA; 2222 } 2223 else if (internalFormat == GL_RGB16F_ARB || 2224 internalFormat == GL_RGB32F_ARB) { 2225 printf("Convert rgb float tex to int %d x %d\n", width, height); 2226 return GL_RGB; 2227 } 2228 else if (internalFormat == GL_LUMINANCE_ALPHA16F_ARB || 2229 internalFormat == GL_LUMINANCE_ALPHA32F_ARB) { 2230 printf("Convert luminance float tex to int %d x %d\n", width, height); 2231 return GL_LUMINANCE_ALPHA; 2232 } 2233 else if (internalFormat == GL_LUMINANCE16F_ARB || 2234 internalFormat == GL_LUMINANCE32F_ARB) { 2235 printf("Convert luminance float tex to int %d x %d\n", width, height); 2236 return GL_LUMINANCE; 2237 } 2238 else if (internalFormat == GL_ALPHA16F_ARB || 2239 internalFormat == GL_ALPHA32F_ARB) { 2240 printf("Convert luminance float tex to int %d x %d\n", width, height); 2241 return GL_ALPHA; 2242 } 2243 /* 2244 else if (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) { 2245 internalFormat = GL_RGBA; 2246 } 2247 */ 2248 else { 2249 return internalFormat; 2250 } 2251#else 2252 return internalFormat; 2253#endif 2254} 2255 2256 2257/** 2258 * Choose the actual hardware format for a texture image. 2259 * Try to use the same format as the previous image level when possible. 2260 * Otherwise, ask the driver for the best format. 2261 * It's important to try to choose a consistant format for all levels 2262 * for efficient texture memory layout/allocation. In particular, this 2263 * comes up during automatic mipmap generation. 2264 */ 2265void 2266_mesa_choose_texture_format(struct gl_context *ctx, 2267 struct gl_texture_object *texObj, 2268 struct gl_texture_image *texImage, 2269 GLenum target, GLint level, 2270 GLenum internalFormat, GLenum format, GLenum type) 2271{ 2272 /* see if we've already chosen a format for the previous level */ 2273 if (level > 0) { 2274 struct gl_texture_image *prevImage = 2275 _mesa_select_tex_image(ctx, texObj, target, level - 1); 2276 /* See if the prev level is defined and has an internal format which 2277 * matches the new internal format. 2278 */ 2279 if (prevImage && 2280 prevImage->Width > 0 && 2281 prevImage->InternalFormat == internalFormat) { 2282 /* use the same format */ 2283 texImage->TexFormat = prevImage->TexFormat; 2284 ASSERT(texImage->TexFormat != MESA_FORMAT_NONE); 2285 return; 2286 } 2287 } 2288 2289 /* choose format from scratch */ 2290 texImage->TexFormat = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, 2291 format, type); 2292 ASSERT(texImage->TexFormat != MESA_FORMAT_NONE); 2293} 2294 2295 2296 2297/* 2298 * Called from the API. Note that width includes the border. 2299 */ 2300void GLAPIENTRY 2301_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, 2302 GLsizei width, GLint border, GLenum format, 2303 GLenum type, const GLvoid *pixels ) 2304{ 2305 GET_CURRENT_CONTEXT(ctx); 2306 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2307 2308 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2309 _mesa_debug(ctx, "glTexImage1D %s %d %s %d %d %s %s %p\n", 2310 _mesa_lookup_enum_by_nr(target), level, 2311 _mesa_lookup_enum_by_nr(internalFormat), width, border, 2312 _mesa_lookup_enum_by_nr(format), 2313 _mesa_lookup_enum_by_nr(type), pixels); 2314 2315 internalFormat = override_internal_format(internalFormat, width, 1); 2316 2317 if (target == GL_TEXTURE_1D) { 2318 /* non-proxy target */ 2319 struct gl_texture_object *texObj; 2320 struct gl_texture_image *texImage; 2321 const GLuint face = _mesa_tex_target_to_face(target); 2322 2323 if (texture_error_check(ctx, target, level, internalFormat, 2324 format, type, 1, width, 1, 1, border)) { 2325 return; /* error was recorded */ 2326 } 2327 2328 if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) 2329 _mesa_update_state(ctx); 2330 2331 texObj = _mesa_get_current_tex_object(ctx, target); 2332 _mesa_lock_texture(ctx, texObj); 2333 { 2334 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 2335 if (!texImage) { 2336 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); 2337 } 2338 else { 2339 if (texImage->Data) { 2340 ctx->Driver.FreeTexImageData( ctx, texImage ); 2341 } 2342 2343 ASSERT(texImage->Data == NULL); 2344 2345 clear_teximage_fields(texImage); /* not really needed, but helpful */ 2346 _mesa_init_teximage_fields(ctx, target, texImage, 2347 width, 1, 1, 2348 border, internalFormat); 2349 2350 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 2351 internalFormat, format, type); 2352 2353 /* Give the texture to the driver. <pixels> may be null. */ 2354 ASSERT(ctx->Driver.TexImage1D); 2355 ctx->Driver.TexImage1D(ctx, target, level, internalFormat, 2356 width, border, format, type, pixels, 2357 &ctx->Unpack, texObj, texImage); 2358 2359 _mesa_set_fetch_functions(texImage, 1); 2360 2361 check_gen_mipmap(ctx, target, texObj, level); 2362 2363 update_fbo_texture(ctx, texObj, face, level); 2364 2365 /* state update */ 2366 texObj->_Complete = GL_FALSE; 2367 ctx->NewState |= _NEW_TEXTURE; 2368 } 2369 } 2370 _mesa_unlock_texture(ctx, texObj); 2371 } 2372 else if (target == GL_PROXY_TEXTURE_1D) { 2373 /* Proxy texture: check for errors and update proxy state */ 2374 struct gl_texture_image *texImage; 2375 texImage = _mesa_get_proxy_tex_image(ctx, target, level); 2376 if (texture_error_check(ctx, target, level, internalFormat, 2377 format, type, 1, width, 1, 1, border)) { 2378 /* when error, clear all proxy texture image parameters */ 2379 if (texImage) 2380 clear_teximage_fields(texImage); 2381 } 2382 else { 2383 /* no error, set the tex image parameters */ 2384 struct gl_texture_object *texObj = 2385 _mesa_get_current_tex_object(ctx, target); 2386 ASSERT(texImage); 2387 _mesa_init_teximage_fields(ctx, target, texImage, 2388 width, 1, 1, 2389 border, internalFormat); 2390 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 2391 internalFormat, format, type); 2392 } 2393 } 2394 else { 2395 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" ); 2396 return; 2397 } 2398} 2399 2400 2401void GLAPIENTRY 2402_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, 2403 GLsizei width, GLsizei height, GLint border, 2404 GLenum format, GLenum type, 2405 const GLvoid *pixels ) 2406{ 2407 GET_CURRENT_CONTEXT(ctx); 2408 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2409 2410 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2411 _mesa_debug(ctx, "glTexImage2D %s %d %s %d %d %d %s %s %p\n", 2412 _mesa_lookup_enum_by_nr(target), level, 2413 _mesa_lookup_enum_by_nr(internalFormat), width, height, 2414 border, _mesa_lookup_enum_by_nr(format), 2415 _mesa_lookup_enum_by_nr(type), pixels); 2416 2417 internalFormat = override_internal_format(internalFormat, width, height); 2418 2419 if (target == GL_TEXTURE_2D || 2420 (ctx->Extensions.ARB_texture_cube_map && 2421 target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 2422 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) || 2423 (ctx->Extensions.NV_texture_rectangle && 2424 target == GL_TEXTURE_RECTANGLE_NV) || 2425 (ctx->Extensions.MESA_texture_array && 2426 target == GL_TEXTURE_1D_ARRAY_EXT)) { 2427 /* non-proxy target */ 2428 struct gl_texture_object *texObj; 2429 struct gl_texture_image *texImage; 2430 const GLuint face = _mesa_tex_target_to_face(target); 2431 2432 if (texture_error_check(ctx, target, level, internalFormat, 2433 format, type, 2, width, height, 1, border)) { 2434 return; /* error was recorded */ 2435 } 2436 2437 if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) 2438 _mesa_update_state(ctx); 2439 2440 texObj = _mesa_get_current_tex_object(ctx, target); 2441 _mesa_lock_texture(ctx, texObj); 2442 { 2443 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 2444 if (!texImage) { 2445 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); 2446 } 2447 else { 2448 if (texImage->Data) { 2449 ctx->Driver.FreeTexImageData( ctx, texImage ); 2450 } 2451 2452 ASSERT(texImage->Data == NULL); 2453 clear_teximage_fields(texImage); /* not really needed, but helpful */ 2454 _mesa_init_teximage_fields(ctx, target, texImage, 2455 width, height, 1, 2456 border, internalFormat); 2457 2458 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 2459 internalFormat, format, type); 2460 2461 /* Give the texture to the driver. <pixels> may be null. */ 2462 ASSERT(ctx->Driver.TexImage2D); 2463 ctx->Driver.TexImage2D(ctx, target, level, internalFormat, 2464 width, height, border, format, type, 2465 pixels, &ctx->Unpack, texObj, texImage); 2466 2467 _mesa_set_fetch_functions(texImage, 2); 2468 2469 check_gen_mipmap(ctx, target, texObj, level); 2470 2471 update_fbo_texture(ctx, texObj, face, level); 2472 2473 /* state update */ 2474 texObj->_Complete = GL_FALSE; 2475 ctx->NewState |= _NEW_TEXTURE; 2476 } 2477 } 2478 _mesa_unlock_texture(ctx, texObj); 2479 } 2480 else if (target == GL_PROXY_TEXTURE_2D || 2481 (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB && 2482 ctx->Extensions.ARB_texture_cube_map) || 2483 (target == GL_PROXY_TEXTURE_RECTANGLE_NV && 2484 ctx->Extensions.NV_texture_rectangle) || 2485 (ctx->Extensions.MESA_texture_array && 2486 target == GL_PROXY_TEXTURE_1D_ARRAY_EXT)) { 2487 /* Proxy texture: check for errors and update proxy state */ 2488 struct gl_texture_image *texImage; 2489 texImage = _mesa_get_proxy_tex_image(ctx, target, level); 2490 if (texture_error_check(ctx, target, level, internalFormat, 2491 format, type, 2, width, height, 1, border)) { 2492 /* when error, clear all proxy texture image parameters */ 2493 if (texImage) 2494 clear_teximage_fields(texImage); 2495 } 2496 else { 2497 /* no error, set the tex image parameters */ 2498 struct gl_texture_object *texObj = 2499 _mesa_get_current_tex_object(ctx, target); 2500 _mesa_init_teximage_fields(ctx, target, texImage, 2501 width, height, 1, 2502 border, internalFormat); 2503 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 2504 internalFormat, format, type); 2505 } 2506 } 2507 else { 2508 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" ); 2509 return; 2510 } 2511} 2512 2513 2514/* 2515 * Called by the API or display list executor. 2516 * Note that width and height include the border. 2517 */ 2518void GLAPIENTRY 2519_mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, 2520 GLsizei width, GLsizei height, GLsizei depth, 2521 GLint border, GLenum format, GLenum type, 2522 const GLvoid *pixels ) 2523{ 2524 GET_CURRENT_CONTEXT(ctx); 2525 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2526 2527 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2528 _mesa_debug(ctx, "glTexImage3D %s %d %s %d %d %d %d %s %s %p\n", 2529 _mesa_lookup_enum_by_nr(target), level, 2530 _mesa_lookup_enum_by_nr(internalFormat), width, height, 2531 depth, border, _mesa_lookup_enum_by_nr(format), 2532 _mesa_lookup_enum_by_nr(type), pixels); 2533 2534 internalFormat = override_internal_format(internalFormat, width, height); 2535 2536 if (target == GL_TEXTURE_3D || 2537 (ctx->Extensions.MESA_texture_array && 2538 target == GL_TEXTURE_2D_ARRAY_EXT)) { 2539 /* non-proxy target */ 2540 struct gl_texture_object *texObj; 2541 struct gl_texture_image *texImage; 2542 const GLuint face = _mesa_tex_target_to_face(target); 2543 2544 if (texture_error_check(ctx, target, level, (GLint) internalFormat, 2545 format, type, 3, width, height, depth, border)) { 2546 return; /* error was recorded */ 2547 } 2548 2549 if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) 2550 _mesa_update_state(ctx); 2551 2552 texObj = _mesa_get_current_tex_object(ctx, target); 2553 _mesa_lock_texture(ctx, texObj); 2554 { 2555 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 2556 if (!texImage) { 2557 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); 2558 } 2559 else { 2560 if (texImage->Data) { 2561 ctx->Driver.FreeTexImageData( ctx, texImage ); 2562 } 2563 2564 ASSERT(texImage->Data == NULL); 2565 clear_teximage_fields(texImage); /* not really needed, but helpful */ 2566 _mesa_init_teximage_fields(ctx, target, texImage, 2567 width, height, depth, 2568 border, internalFormat); 2569 2570 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 2571 internalFormat, format, type); 2572 2573 /* Give the texture to the driver. <pixels> may be null. */ 2574 ASSERT(ctx->Driver.TexImage3D); 2575 ctx->Driver.TexImage3D(ctx, target, level, internalFormat, 2576 width, height, depth, border, format, type, 2577 pixels, &ctx->Unpack, texObj, texImage); 2578 2579 _mesa_set_fetch_functions(texImage, 3); 2580 2581 check_gen_mipmap(ctx, target, texObj, level); 2582 2583 update_fbo_texture(ctx, texObj, face, level); 2584 2585 /* state update */ 2586 texObj->_Complete = GL_FALSE; 2587 ctx->NewState |= _NEW_TEXTURE; 2588 } 2589 } 2590 _mesa_unlock_texture(ctx, texObj); 2591 } 2592 else if (target == GL_PROXY_TEXTURE_3D || 2593 (ctx->Extensions.MESA_texture_array && 2594 target == GL_PROXY_TEXTURE_2D_ARRAY_EXT)) { 2595 /* Proxy texture: check for errors and update proxy state */ 2596 struct gl_texture_image *texImage; 2597 texImage = _mesa_get_proxy_tex_image(ctx, target, level); 2598 if (texture_error_check(ctx, target, level, internalFormat, 2599 format, type, 3, width, height, depth, border)) { 2600 /* when error, clear all proxy texture image parameters */ 2601 if (texImage) 2602 clear_teximage_fields(texImage); 2603 } 2604 else { 2605 /* no error, set the tex image parameters */ 2606 struct gl_texture_object *texObj = 2607 _mesa_get_current_tex_object(ctx, target); 2608 _mesa_init_teximage_fields(ctx, target, texImage, width, height, 2609 depth, border, internalFormat); 2610 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 2611 internalFormat, format, type); 2612 } 2613 } 2614 else { 2615 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" ); 2616 return; 2617 } 2618} 2619 2620 2621void GLAPIENTRY 2622_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat, 2623 GLsizei width, GLsizei height, GLsizei depth, 2624 GLint border, GLenum format, GLenum type, 2625 const GLvoid *pixels ) 2626{ 2627 _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height, 2628 depth, border, format, type, pixels); 2629} 2630 2631 2632#if FEATURE_OES_EGL_image 2633void GLAPIENTRY 2634_mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) 2635{ 2636 struct gl_texture_object *texObj; 2637 struct gl_texture_image *texImage; 2638 GET_CURRENT_CONTEXT(ctx); 2639 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2640 2641 if (!ctx->Extensions.OES_EGL_image) { 2642 _mesa_error(ctx, GL_INVALID_OPERATION, 2643 "glEGLImageTargetTexture2DOES(unsupported)"); 2644 return; 2645 } 2646 2647 if (target != GL_TEXTURE_2D) { 2648 _mesa_error(ctx, GL_INVALID_ENUM, 2649 "glEGLImageTargetTexture2D(target=%d)", target); 2650 return; 2651 } 2652 2653 if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) 2654 _mesa_update_state(ctx); 2655 2656 texObj = _mesa_get_current_tex_object(ctx, target); 2657 _mesa_lock_texture(ctx, texObj); 2658 2659 texImage = _mesa_get_tex_image(ctx, texObj, target, 0); 2660 if (!texImage) { 2661 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEGLImageTargetTexture2D"); 2662 } else { 2663 if (texImage->Data) 2664 ctx->Driver.FreeTexImageData( ctx, texImage ); 2665 2666 ASSERT(texImage->Data == NULL); 2667 ctx->Driver.EGLImageTargetTexture2D(ctx, target, 2668 texObj, texImage, image); 2669 2670 /* state update */ 2671 texObj->_Complete = GL_FALSE; 2672 ctx->NewState |= _NEW_TEXTURE; 2673 } 2674 _mesa_unlock_texture(ctx, texObj); 2675 2676} 2677#endif 2678 2679 2680void GLAPIENTRY 2681_mesa_TexSubImage1D( GLenum target, GLint level, 2682 GLint xoffset, GLsizei width, 2683 GLenum format, GLenum type, 2684 const GLvoid *pixels ) 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 (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2692 _mesa_debug(ctx, "glTexSubImage1D %s %d %d %d %s %s %p\n", 2693 _mesa_lookup_enum_by_nr(target), level, 2694 xoffset, width, _mesa_lookup_enum_by_nr(format), 2695 _mesa_lookup_enum_by_nr(type), pixels); 2696 2697 if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) 2698 _mesa_update_state(ctx); 2699 2700 if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0, 2701 width, 1, 1, format, type)) { 2702 return; /* error was detected */ 2703 } 2704 2705 2706 texObj = _mesa_get_current_tex_object(ctx, target); 2707 assert(texObj); 2708 2709 _mesa_lock_texture(ctx, texObj); 2710 { 2711 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 2712 2713 if (subtexture_error_check2(ctx, 1, target, level, xoffset, 0, 0, 2714 width, 1, 1, format, type, texImage)) { 2715 /* error was recorded */ 2716 } 2717 else if (width > 0) { 2718 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 2719 xoffset += texImage->Border; 2720 2721 ASSERT(ctx->Driver.TexSubImage1D); 2722 ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width, 2723 format, type, pixels, &ctx->Unpack, 2724 texObj, texImage); 2725 2726 check_gen_mipmap(ctx, target, texObj, level); 2727 2728 ctx->NewState |= _NEW_TEXTURE; 2729 } 2730 } 2731 _mesa_unlock_texture(ctx, texObj); 2732} 2733 2734 2735void GLAPIENTRY 2736_mesa_TexSubImage2D( GLenum target, GLint level, 2737 GLint xoffset, GLint yoffset, 2738 GLsizei width, GLsizei height, 2739 GLenum format, GLenum type, 2740 const GLvoid *pixels ) 2741{ 2742 struct gl_texture_object *texObj; 2743 struct gl_texture_image *texImage; 2744 GET_CURRENT_CONTEXT(ctx); 2745 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2746 2747 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2748 _mesa_debug(ctx, "glTexSubImage2D %s %d %d %d %d %d %s %s %p\n", 2749 _mesa_lookup_enum_by_nr(target), level, 2750 xoffset, yoffset, width, height, 2751 _mesa_lookup_enum_by_nr(format), 2752 _mesa_lookup_enum_by_nr(type), pixels); 2753 2754 if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) 2755 _mesa_update_state(ctx); 2756 2757 if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0, 2758 width, height, 1, format, type)) { 2759 return; /* error was detected */ 2760 } 2761 2762 texObj = _mesa_get_current_tex_object(ctx, target); 2763 2764 _mesa_lock_texture(ctx, texObj); 2765 { 2766 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 2767 2768 if (subtexture_error_check2(ctx, 2, target, level, xoffset, yoffset, 0, 2769 width, height, 1, format, type, texImage)) { 2770 /* error was recorded */ 2771 } 2772 else if (width > 0 && height >= 0) { 2773 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 2774 xoffset += texImage->Border; 2775 yoffset += texImage->Border; 2776 2777 ASSERT(ctx->Driver.TexSubImage2D); 2778 ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset, 2779 width, height, format, type, pixels, 2780 &ctx->Unpack, texObj, texImage); 2781 2782 check_gen_mipmap(ctx, target, texObj, level); 2783 2784 ctx->NewState |= _NEW_TEXTURE; 2785 } 2786 } 2787 _mesa_unlock_texture(ctx, texObj); 2788} 2789 2790 2791 2792void GLAPIENTRY 2793_mesa_TexSubImage3D( GLenum target, GLint level, 2794 GLint xoffset, GLint yoffset, GLint zoffset, 2795 GLsizei width, GLsizei height, GLsizei depth, 2796 GLenum format, GLenum type, 2797 const GLvoid *pixels ) 2798{ 2799 struct gl_texture_object *texObj; 2800 struct gl_texture_image *texImage; 2801 GET_CURRENT_CONTEXT(ctx); 2802 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2803 2804 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2805 _mesa_debug(ctx, "glTexSubImage3D %s %d %d %d %d %d %d %d %s %s %p\n", 2806 _mesa_lookup_enum_by_nr(target), level, 2807 xoffset, yoffset, zoffset, width, height, depth, 2808 _mesa_lookup_enum_by_nr(format), 2809 _mesa_lookup_enum_by_nr(type), pixels); 2810 2811 if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) 2812 _mesa_update_state(ctx); 2813 2814 if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset, 2815 width, height, depth, format, type)) { 2816 return; /* error was detected */ 2817 } 2818 2819 texObj = _mesa_get_current_tex_object(ctx, target); 2820 2821 _mesa_lock_texture(ctx, texObj); 2822 { 2823 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 2824 2825 if (subtexture_error_check2(ctx, 3, target, level, 2826 xoffset, yoffset, zoffset, 2827 width, height, depth, 2828 format, type, texImage)) { 2829 /* error was recorded */ 2830 } 2831 else if (width > 0 && height > 0 && height > 0) { 2832 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 2833 xoffset += texImage->Border; 2834 yoffset += texImage->Border; 2835 zoffset += texImage->Border; 2836 2837 ASSERT(ctx->Driver.TexSubImage3D); 2838 ctx->Driver.TexSubImage3D(ctx, target, level, 2839 xoffset, yoffset, zoffset, 2840 width, height, depth, 2841 format, type, pixels, 2842 &ctx->Unpack, texObj, texImage ); 2843 2844 check_gen_mipmap(ctx, target, texObj, level); 2845 2846 ctx->NewState |= _NEW_TEXTURE; 2847 } 2848 } 2849 _mesa_unlock_texture(ctx, texObj); 2850} 2851 2852 2853 2854void GLAPIENTRY 2855_mesa_CopyTexImage1D( GLenum target, GLint level, 2856 GLenum internalFormat, 2857 GLint x, GLint y, 2858 GLsizei width, GLint border ) 2859{ 2860 struct gl_texture_object *texObj; 2861 struct gl_texture_image *texImage; 2862 const GLuint face = _mesa_tex_target_to_face(target); 2863 GET_CURRENT_CONTEXT(ctx); 2864 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2865 2866 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2867 _mesa_debug(ctx, "glCopyTexImage1D %s %d %s %d %d %d %d\n", 2868 _mesa_lookup_enum_by_nr(target), level, 2869 _mesa_lookup_enum_by_nr(internalFormat), 2870 x, y, width, border); 2871 2872 if (ctx->NewState & NEW_COPY_TEX_STATE) 2873 _mesa_update_state(ctx); 2874 2875 if (copytexture_error_check(ctx, 1, target, level, internalFormat, 2876 width, 1, border)) 2877 return; 2878 2879 texObj = _mesa_get_current_tex_object(ctx, target); 2880 2881 _mesa_lock_texture(ctx, texObj); 2882 { 2883 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 2884 if (!texImage) { 2885 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); 2886 } 2887 else { 2888 if (texImage->Data) { 2889 ctx->Driver.FreeTexImageData( ctx, texImage ); 2890 } 2891 2892 ASSERT(texImage->Data == NULL); 2893 2894 clear_teximage_fields(texImage); /* not really needed, but helpful */ 2895 _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, 2896 border, internalFormat); 2897 2898 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 2899 internalFormat, GL_NONE, GL_NONE); 2900 2901 ASSERT(ctx->Driver.CopyTexImage1D); 2902 ctx->Driver.CopyTexImage1D(ctx, target, level, internalFormat, 2903 x, y, width, border); 2904 2905 _mesa_set_fetch_functions(texImage, 1); 2906 2907 check_gen_mipmap(ctx, target, texObj, level); 2908 2909 update_fbo_texture(ctx, texObj, face, level); 2910 2911 /* state update */ 2912 texObj->_Complete = GL_FALSE; 2913 ctx->NewState |= _NEW_TEXTURE; 2914 } 2915 } 2916 _mesa_unlock_texture(ctx, texObj); 2917} 2918 2919 2920 2921void GLAPIENTRY 2922_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, 2923 GLint x, GLint y, GLsizei width, GLsizei height, 2924 GLint border ) 2925{ 2926 struct gl_texture_object *texObj; 2927 struct gl_texture_image *texImage; 2928 const GLuint face = _mesa_tex_target_to_face(target); 2929 GET_CURRENT_CONTEXT(ctx); 2930 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2931 2932 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2933 _mesa_debug(ctx, "glCopyTexImage2D %s %d %s %d %d %d %d %d\n", 2934 _mesa_lookup_enum_by_nr(target), level, 2935 _mesa_lookup_enum_by_nr(internalFormat), 2936 x, y, width, height, border); 2937 2938 if (ctx->NewState & NEW_COPY_TEX_STATE) 2939 _mesa_update_state(ctx); 2940 2941 if (copytexture_error_check(ctx, 2, target, level, internalFormat, 2942 width, height, border)) 2943 return; 2944 2945 texObj = _mesa_get_current_tex_object(ctx, target); 2946 2947 _mesa_lock_texture(ctx, texObj); 2948 { 2949 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 2950 2951 if (!texImage) { 2952 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); 2953 } 2954 else { 2955 if (texImage->Data) { 2956 ctx->Driver.FreeTexImageData( ctx, texImage ); 2957 } 2958 2959 ASSERT(texImage->Data == NULL); 2960 2961 clear_teximage_fields(texImage); /* not really needed, but helpful */ 2962 _mesa_init_teximage_fields(ctx, target, texImage, 2963 width, height, 1, 2964 border, internalFormat); 2965 2966 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 2967 internalFormat, GL_NONE, GL_NONE); 2968 2969 ASSERT(ctx->Driver.CopyTexImage2D); 2970 ctx->Driver.CopyTexImage2D(ctx, target, level, internalFormat, 2971 x, y, width, height, border); 2972 2973 _mesa_set_fetch_functions(texImage, 2); 2974 2975 check_gen_mipmap(ctx, target, texObj, level); 2976 2977 update_fbo_texture(ctx, texObj, face, level); 2978 2979 /* state update */ 2980 texObj->_Complete = GL_FALSE; 2981 ctx->NewState |= _NEW_TEXTURE; 2982 } 2983 } 2984 _mesa_unlock_texture(ctx, texObj); 2985} 2986 2987 2988void GLAPIENTRY 2989_mesa_CopyTexSubImage1D( GLenum target, GLint level, 2990 GLint xoffset, GLint x, GLint y, GLsizei width ) 2991{ 2992 struct gl_texture_object *texObj; 2993 struct gl_texture_image *texImage; 2994 GLint yoffset = 0; 2995 GLsizei height = 1; 2996 2997 GET_CURRENT_CONTEXT(ctx); 2998 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2999 3000 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3001 _mesa_debug(ctx, "glCopyTexSubImage1D %s %d %d %d %d %d\n", 3002 _mesa_lookup_enum_by_nr(target), 3003 level, xoffset, x, y, width); 3004 3005 if (ctx->NewState & NEW_COPY_TEX_STATE) 3006 _mesa_update_state(ctx); 3007 3008 if (copytexsubimage_error_check1(ctx, 1, target, level)) 3009 return; 3010 3011 texObj = _mesa_get_current_tex_object(ctx, target); 3012 3013 _mesa_lock_texture(ctx, texObj); 3014 { 3015 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3016 3017 if (copytexsubimage_error_check2(ctx, 1, target, level, 3018 xoffset, 0, 0, width, 1, texImage)) { 3019 /* error was recorded */ 3020 } 3021 else { 3022 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 3023 xoffset += texImage->Border; 3024 3025 if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, 3026 &width, &height)) { 3027 ASSERT(ctx->Driver.CopyTexSubImage1D); 3028 ctx->Driver.CopyTexSubImage1D(ctx, target, level, 3029 xoffset, x, y, width); 3030 3031 check_gen_mipmap(ctx, target, texObj, level); 3032 3033 ctx->NewState |= _NEW_TEXTURE; 3034 } 3035 } 3036 } 3037 _mesa_unlock_texture(ctx, texObj); 3038} 3039 3040 3041 3042void GLAPIENTRY 3043_mesa_CopyTexSubImage2D( GLenum target, GLint level, 3044 GLint xoffset, GLint yoffset, 3045 GLint x, GLint y, GLsizei width, GLsizei height ) 3046{ 3047 struct gl_texture_object *texObj; 3048 struct gl_texture_image *texImage; 3049 GET_CURRENT_CONTEXT(ctx); 3050 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3051 3052 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3053 _mesa_debug(ctx, "glCopyTexSubImage2D %s %d %d %d %d %d %d %d\n", 3054 _mesa_lookup_enum_by_nr(target), 3055 level, xoffset, yoffset, x, y, width, height); 3056 3057 if (ctx->NewState & NEW_COPY_TEX_STATE) 3058 _mesa_update_state(ctx); 3059 3060 if (copytexsubimage_error_check1(ctx, 2, target, level)) 3061 return; 3062 3063 texObj = _mesa_get_current_tex_object(ctx, target); 3064 3065 _mesa_lock_texture(ctx, texObj); 3066 { 3067 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3068 3069 if (copytexsubimage_error_check2(ctx, 2, target, level, 3070 xoffset, yoffset, 0, 3071 width, height, texImage)) { 3072 /* error was recorded */ 3073 } 3074 else { 3075 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 3076 xoffset += texImage->Border; 3077 yoffset += texImage->Border; 3078 3079 if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, 3080 &width, &height)) { 3081 ASSERT(ctx->Driver.CopyTexSubImage2D); 3082 ctx->Driver.CopyTexSubImage2D(ctx, target, level, xoffset, yoffset, 3083 x, y, width, height); 3084 3085 check_gen_mipmap(ctx, target, texObj, level); 3086 3087 ctx->NewState |= _NEW_TEXTURE; 3088 } 3089 } 3090 } 3091 _mesa_unlock_texture(ctx, texObj); 3092} 3093 3094 3095 3096void GLAPIENTRY 3097_mesa_CopyTexSubImage3D( GLenum target, GLint level, 3098 GLint xoffset, GLint yoffset, GLint zoffset, 3099 GLint x, GLint y, GLsizei width, GLsizei height ) 3100{ 3101 struct gl_texture_object *texObj; 3102 struct gl_texture_image *texImage; 3103 GET_CURRENT_CONTEXT(ctx); 3104 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3105 3106 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3107 _mesa_debug(ctx, "glCopyTexSubImage3D %s %d %d %d %d %d %d %d %d\n", 3108 _mesa_lookup_enum_by_nr(target), 3109 level, xoffset, yoffset, zoffset, x, y, width, height); 3110 3111 if (ctx->NewState & NEW_COPY_TEX_STATE) 3112 _mesa_update_state(ctx); 3113 3114 if (copytexsubimage_error_check1(ctx, 3, target, level)) 3115 return; 3116 3117 texObj = _mesa_get_current_tex_object(ctx, target); 3118 3119 _mesa_lock_texture(ctx, texObj); 3120 { 3121 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3122 3123 if (copytexsubimage_error_check2(ctx, 3, target, level, xoffset, yoffset, 3124 zoffset, width, height, texImage)) { 3125 /* error was recored */ 3126 } 3127 else { 3128 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 3129 xoffset += texImage->Border; 3130 yoffset += texImage->Border; 3131 zoffset += texImage->Border; 3132 3133 if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, 3134 &width, &height)) { 3135 ASSERT(ctx->Driver.CopyTexSubImage3D); 3136 ctx->Driver.CopyTexSubImage3D(ctx, target, level, 3137 xoffset, yoffset, zoffset, 3138 x, y, width, height); 3139 3140 check_gen_mipmap(ctx, target, texObj, level); 3141 3142 ctx->NewState |= _NEW_TEXTURE; 3143 } 3144 } 3145 } 3146 _mesa_unlock_texture(ctx, texObj); 3147} 3148 3149 3150 3151 3152/**********************************************************************/ 3153/****** Compressed Textures ******/ 3154/**********************************************************************/ 3155 3156 3157/** 3158 * Return expected size of a compressed texture. 3159 */ 3160static GLuint 3161compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth, 3162 GLenum glformat) 3163{ 3164 gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat); 3165 return _mesa_format_image_size(mesaFormat, width, height, depth); 3166} 3167 3168 3169/* 3170 * Return compressed texture block size, in pixels. 3171 */ 3172static void 3173get_compressed_block_size(GLenum glformat, GLuint *bw, GLuint *bh) 3174{ 3175 gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat); 3176 _mesa_get_format_block_size(mesaFormat, bw, bh); 3177} 3178 3179 3180/** 3181 * Error checking for glCompressedTexImage[123]D(). 3182 * \return error code or GL_NO_ERROR. 3183 */ 3184static GLenum 3185compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, 3186 GLenum target, GLint level, 3187 GLenum internalFormat, GLsizei width, 3188 GLsizei height, GLsizei depth, GLint border, 3189 GLsizei imageSize) 3190{ 3191 GLint expectedSize, maxLevels = 0, maxTextureSize; 3192 3193 if (dimensions == 1) { 3194 /* 1D compressed textures not allowed */ 3195 return GL_INVALID_ENUM; 3196 } 3197 else if (dimensions == 2) { 3198 if (target == GL_PROXY_TEXTURE_2D) { 3199 maxLevels = ctx->Const.MaxTextureLevels; 3200 } 3201 else if (target == GL_TEXTURE_2D) { 3202 maxLevels = ctx->Const.MaxTextureLevels; 3203 } 3204 else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { 3205 if (!ctx->Extensions.ARB_texture_cube_map) 3206 return GL_INVALID_ENUM; /*target*/ 3207 maxLevels = ctx->Const.MaxCubeTextureLevels; 3208 } 3209 else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 3210 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 3211 if (!ctx->Extensions.ARB_texture_cube_map) 3212 return GL_INVALID_ENUM; /*target*/ 3213 maxLevels = ctx->Const.MaxCubeTextureLevels; 3214 } 3215 else { 3216 return GL_INVALID_ENUM; /*target*/ 3217 } 3218 } 3219 else if (dimensions == 3) { 3220 /* 3D compressed textures not allowed */ 3221 return GL_INVALID_ENUM; 3222 } 3223 else { 3224 assert(0); 3225 return GL_INVALID_ENUM; 3226 } 3227 3228 maxTextureSize = 1 << (maxLevels - 1); 3229 3230 /* This will detect any invalid internalFormat value */ 3231 if (!_mesa_is_compressed_format(ctx, internalFormat)) 3232 return GL_INVALID_ENUM; 3233 3234 /* This should really never fail */ 3235 if (_mesa_base_tex_format(ctx, internalFormat) < 0) 3236 return GL_INVALID_ENUM; 3237 3238 if (border != 0) 3239 return GL_INVALID_VALUE; 3240 3241 /* 3242 * XXX We should probably use the proxy texture error check function here. 3243 */ 3244 if (width < 1 || width > maxTextureSize || 3245 (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(width))) 3246 return GL_INVALID_VALUE; 3247 3248 if ((height < 1 || height > maxTextureSize || 3249 (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(height))) 3250 && dimensions > 1) 3251 return GL_INVALID_VALUE; 3252 3253 if ((depth < 1 || depth > maxTextureSize || 3254 (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(depth))) 3255 && dimensions > 2) 3256 return GL_INVALID_VALUE; 3257 3258 /* For cube map, width must equal height */ 3259 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 3260 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB && width != height) 3261 return GL_INVALID_VALUE; 3262 3263 if (level < 0 || level >= maxLevels) 3264 return GL_INVALID_VALUE; 3265 3266 expectedSize = compressed_tex_size(width, height, depth, internalFormat); 3267 if (expectedSize != imageSize) 3268 return GL_INVALID_VALUE; 3269 3270#if FEATURE_EXT_texture_sRGB 3271 if ((internalFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT || 3272 internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT || 3273 internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT || 3274 internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT) 3275 && border != 0) { 3276 return GL_INVALID_OPERATION; 3277 } 3278#endif 3279 3280 return GL_NO_ERROR; 3281} 3282 3283 3284/** 3285 * Error checking for glCompressedTexSubImage[123]D(). 3286 * \warning There are some bad assumptions here about the size of compressed 3287 * texture tiles (multiple of 4) used to test the validity of the 3288 * offset and size parameters. 3289 * \return error code or GL_NO_ERROR. 3290 */ 3291static GLenum 3292compressed_subtexture_error_check(struct gl_context *ctx, GLint dimensions, 3293 GLenum target, GLint level, 3294 GLint xoffset, GLint yoffset, GLint zoffset, 3295 GLsizei width, GLsizei height, GLsizei depth, 3296 GLenum format, GLsizei imageSize) 3297{ 3298 GLint expectedSize, maxLevels = 0, maxTextureSize; 3299 GLuint bw, bh; 3300 (void) zoffset; 3301 3302 if (dimensions == 1) { 3303 /* 1D compressed textures not allowed */ 3304 return GL_INVALID_ENUM; 3305 } 3306 else if (dimensions == 2) { 3307 if (target == GL_PROXY_TEXTURE_2D) { 3308 maxLevels = ctx->Const.MaxTextureLevels; 3309 } 3310 else if (target == GL_TEXTURE_2D) { 3311 maxLevels = ctx->Const.MaxTextureLevels; 3312 } 3313 else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { 3314 if (!ctx->Extensions.ARB_texture_cube_map) 3315 return GL_INVALID_ENUM; /*target*/ 3316 maxLevels = ctx->Const.MaxCubeTextureLevels; 3317 } 3318 else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 3319 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 3320 if (!ctx->Extensions.ARB_texture_cube_map) 3321 return GL_INVALID_ENUM; /*target*/ 3322 maxLevels = ctx->Const.MaxCubeTextureLevels; 3323 } 3324 else { 3325 return GL_INVALID_ENUM; /*target*/ 3326 } 3327 } 3328 else if (dimensions == 3) { 3329 /* 3D compressed textures not allowed */ 3330 return GL_INVALID_ENUM; 3331 } 3332 3333 maxTextureSize = 1 << (maxLevels - 1); 3334 3335 /* this will catch any invalid compressed format token */ 3336 if (!_mesa_is_compressed_format(ctx, format)) 3337 return GL_INVALID_ENUM; 3338 3339 if (width < 1 || width > maxTextureSize) 3340 return GL_INVALID_VALUE; 3341 3342 if ((height < 1 || height > maxTextureSize) 3343 && dimensions > 1) 3344 return GL_INVALID_VALUE; 3345 3346 if (level < 0 || level >= maxLevels) 3347 return GL_INVALID_VALUE; 3348 3349 /* 3350 * do checks which depend on compression block size 3351 */ 3352 get_compressed_block_size(format, &bw, &bh); 3353 3354 if ((xoffset % bw != 0) || (yoffset % bh != 0)) 3355 return GL_INVALID_VALUE; 3356 3357 if ((width % bw != 0) && width != 2 && width != 1) 3358 return GL_INVALID_VALUE; 3359 3360 if ((height % bh != 0) && height != 2 && height != 1) 3361 return GL_INVALID_VALUE; 3362 3363 expectedSize = compressed_tex_size(width, height, depth, format); 3364 if (expectedSize != imageSize) 3365 return GL_INVALID_VALUE; 3366 3367 return GL_NO_ERROR; 3368} 3369 3370 3371/** 3372 * Do second part of glCompressedTexSubImage error checking. 3373 * \return GL_TRUE if error found, GL_FALSE otherwise. 3374 */ 3375static GLboolean 3376compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims, 3377 GLsizei width, GLsizei height, 3378 GLsizei depth, GLenum format, 3379 struct gl_texture_image *texImage) 3380{ 3381 3382 if ((GLint) format != texImage->InternalFormat) { 3383 _mesa_error(ctx, GL_INVALID_OPERATION, 3384 "glCompressedTexSubImage%uD(format=0x%x)", dims, format); 3385 return GL_TRUE; 3386 } 3387 3388 if (((width == 1 || width == 2) && 3389 width != (GLsizei) texImage->Width) || 3390 (width > (GLsizei) texImage->Width)) { 3391 _mesa_error(ctx, GL_INVALID_VALUE, 3392 "glCompressedTexSubImage%uD(width=%d)", dims, width); 3393 return GL_TRUE; 3394 } 3395 3396 if (dims >= 2) { 3397 if (((height == 1 || height == 2) && 3398 height != (GLsizei) texImage->Height) || 3399 (height > (GLsizei) texImage->Height)) { 3400 _mesa_error(ctx, GL_INVALID_VALUE, 3401 "glCompressedTexSubImage%uD(height=%d)", dims, height); 3402 return GL_TRUE; 3403 } 3404 } 3405 3406 if (dims >= 3) { 3407 if (((depth == 1 || depth == 2) && 3408 depth != (GLsizei) texImage->Depth) || 3409 (depth > (GLsizei) texImage->Depth)) { 3410 _mesa_error(ctx, GL_INVALID_VALUE, 3411 "glCompressedTexSubImage%uD(depth=%d)", dims, depth); 3412 return GL_TRUE; 3413 } 3414 } 3415 3416 return GL_FALSE; 3417} 3418 3419 3420 3421void GLAPIENTRY 3422_mesa_CompressedTexImage1DARB(GLenum target, GLint level, 3423 GLenum internalFormat, GLsizei width, 3424 GLint border, GLsizei imageSize, 3425 const GLvoid *data) 3426{ 3427 GET_CURRENT_CONTEXT(ctx); 3428 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3429 3430 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3431 _mesa_debug(ctx, "glCompressedTexImage1DARB %s %d %s %d %d %d %p\n", 3432 _mesa_lookup_enum_by_nr(target), level, 3433 _mesa_lookup_enum_by_nr(internalFormat), 3434 width, border, imageSize, data); 3435 3436 if (target == GL_TEXTURE_1D) { 3437 /* non-proxy target */ 3438 struct gl_texture_object *texObj; 3439 struct gl_texture_image *texImage; 3440 GLenum error = compressed_texture_error_check(ctx, 1, target, level, 3441 internalFormat, width, 1, 1, border, imageSize); 3442 if (error) { 3443 _mesa_error(ctx, error, "glCompressedTexImage1D"); 3444 return; 3445 } 3446 3447 texObj = _mesa_get_current_tex_object(ctx, target); 3448 3449 _mesa_lock_texture(ctx, texObj); 3450 { 3451 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 3452 if (!texImage) { 3453 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D"); 3454 } 3455 else { 3456 if (texImage->Data) { 3457 ctx->Driver.FreeTexImageData( ctx, texImage ); 3458 } 3459 ASSERT(texImage->Data == NULL); 3460 3461 _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, 3462 border, internalFormat); 3463 3464 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 3465 internalFormat, GL_NONE, GL_NONE); 3466 3467 ASSERT(ctx->Driver.CompressedTexImage1D); 3468 ctx->Driver.CompressedTexImage1D(ctx, target, level, 3469 internalFormat, width, border, 3470 imageSize, data, 3471 texObj, texImage); 3472 3473 _mesa_set_fetch_functions(texImage, 1); 3474 3475 check_gen_mipmap(ctx, target, texObj, level); 3476 3477 /* state update */ 3478 texObj->_Complete = GL_FALSE; 3479 ctx->NewState |= _NEW_TEXTURE; 3480 } 3481 } 3482 _mesa_unlock_texture(ctx, texObj); 3483 } 3484 else if (target == GL_PROXY_TEXTURE_1D) { 3485 /* Proxy texture: check for errors and update proxy state */ 3486 GLenum error = compressed_texture_error_check(ctx, 1, target, level, 3487 internalFormat, width, 1, 1, border, imageSize); 3488 if (!error) { 3489 ASSERT(ctx->Driver.TestProxyTexImage); 3490 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 3491 internalFormat, GL_NONE, GL_NONE, 3492 width, 1, 1, border); 3493 } 3494 if (error) { 3495 /* if error, clear all proxy texture image parameters */ 3496 struct gl_texture_image *texImage; 3497 texImage = _mesa_get_proxy_tex_image(ctx, target, level); 3498 if (texImage) 3499 clear_teximage_fields(texImage); 3500 } 3501 else { 3502 /* store the teximage parameters */ 3503 struct gl_texture_object *texObj; 3504 struct gl_texture_image *texImage; 3505 3506 texObj = _mesa_get_current_tex_object(ctx, target); 3507 3508 _mesa_lock_texture(ctx, texObj); 3509 { 3510 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3511 _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, 3512 border, internalFormat); 3513 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 3514 internalFormat, GL_NONE, GL_NONE); 3515 } 3516 _mesa_unlock_texture(ctx, texObj); 3517 } 3518 } 3519 else { 3520 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1D(target)"); 3521 return; 3522 } 3523} 3524 3525void GLAPIENTRY 3526_mesa_CompressedTexImage2DARB(GLenum target, GLint level, 3527 GLenum internalFormat, GLsizei width, 3528 GLsizei height, GLint border, GLsizei imageSize, 3529 const GLvoid *data) 3530{ 3531 GET_CURRENT_CONTEXT(ctx); 3532 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3533 3534 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3535 _mesa_debug(ctx, "glCompressedTexImage2DARB %s %d %s %d %d %d %d %p\n", 3536 _mesa_lookup_enum_by_nr(target), level, 3537 _mesa_lookup_enum_by_nr(internalFormat), 3538 width, height, border, imageSize, data); 3539 3540#if FEATURE_ES 3541 switch (internalFormat) { 3542 case GL_PALETTE4_RGB8_OES: 3543 case GL_PALETTE4_RGBA8_OES: 3544 case GL_PALETTE4_R5_G6_B5_OES: 3545 case GL_PALETTE4_RGBA4_OES: 3546 case GL_PALETTE4_RGB5_A1_OES: 3547 case GL_PALETTE8_RGB8_OES: 3548 case GL_PALETTE8_RGBA8_OES: 3549 case GL_PALETTE8_R5_G6_B5_OES: 3550 case GL_PALETTE8_RGBA4_OES: 3551 case GL_PALETTE8_RGB5_A1_OES: 3552 _mesa_cpal_compressed_teximage2d(target, level, internalFormat, 3553 width, height, imageSize, data); 3554 return; 3555 } 3556#endif 3557 3558 if (target == GL_TEXTURE_2D || 3559 (ctx->Extensions.ARB_texture_cube_map && 3560 target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 3561 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { 3562 /* non-proxy target */ 3563 struct gl_texture_object *texObj; 3564 struct gl_texture_image *texImage; 3565 3566 GLenum error = compressed_texture_error_check(ctx, 2, target, level, 3567 internalFormat, width, height, 1, border, imageSize); 3568 if (error) { 3569 _mesa_error(ctx, error, "glCompressedTexImage2D"); 3570 return; 3571 } 3572 3573 texObj = _mesa_get_current_tex_object(ctx, target); 3574 3575 _mesa_lock_texture(ctx, texObj); 3576 { 3577 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 3578 if (!texImage) { 3579 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); 3580 } 3581 else { 3582 if (texImage->Data) { 3583 ctx->Driver.FreeTexImageData( ctx, texImage ); 3584 } 3585 ASSERT(texImage->Data == NULL); 3586 3587 _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, 3588 border, internalFormat); 3589 3590 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 3591 internalFormat, GL_NONE, GL_NONE); 3592 3593 ASSERT(ctx->Driver.CompressedTexImage2D); 3594 ctx->Driver.CompressedTexImage2D(ctx, target, level, 3595 internalFormat, width, height, 3596 border, imageSize, data, 3597 texObj, texImage); 3598 3599 _mesa_set_fetch_functions(texImage, 2); 3600 3601 check_gen_mipmap(ctx, target, texObj, level); 3602 3603 /* state update */ 3604 texObj->_Complete = GL_FALSE; 3605 ctx->NewState |= _NEW_TEXTURE; 3606 } 3607 } 3608 _mesa_unlock_texture(ctx, texObj); 3609 } 3610 else if (target == GL_PROXY_TEXTURE_2D || 3611 (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB && 3612 ctx->Extensions.ARB_texture_cube_map)) { 3613 /* Proxy texture: check for errors and update proxy state */ 3614 GLenum error = compressed_texture_error_check(ctx, 2, target, level, 3615 internalFormat, width, height, 1, border, imageSize); 3616 if (!error) { 3617 ASSERT(ctx->Driver.TestProxyTexImage); 3618 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 3619 internalFormat, GL_NONE, GL_NONE, 3620 width, height, 1, border); 3621 } 3622 if (error) { 3623 /* if error, clear all proxy texture image parameters */ 3624 struct gl_texture_image *texImage; 3625 texImage = _mesa_get_proxy_tex_image(ctx, target, level); 3626 if (texImage) 3627 clear_teximage_fields(texImage); 3628 } 3629 else { 3630 /* store the teximage parameters */ 3631 struct gl_texture_object *texObj; 3632 struct gl_texture_image *texImage; 3633 3634 texObj = _mesa_get_current_tex_object(ctx, target); 3635 3636 _mesa_lock_texture(ctx, texObj); 3637 { 3638 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3639 _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, 3640 border, internalFormat); 3641 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 3642 internalFormat, GL_NONE, GL_NONE); 3643 } 3644 _mesa_unlock_texture(ctx, texObj); 3645 } 3646 } 3647 else { 3648 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(target)"); 3649 return; 3650 } 3651} 3652 3653 3654void GLAPIENTRY 3655_mesa_CompressedTexImage3DARB(GLenum target, GLint level, 3656 GLenum internalFormat, GLsizei width, 3657 GLsizei height, GLsizei depth, GLint border, 3658 GLsizei imageSize, const GLvoid *data) 3659{ 3660 GET_CURRENT_CONTEXT(ctx); 3661 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3662 3663 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3664 _mesa_debug(ctx, "glCompressedTexImage3DARB %s %d %s %d %d %d %d %d %p\n", 3665 _mesa_lookup_enum_by_nr(target), level, 3666 _mesa_lookup_enum_by_nr(internalFormat), 3667 width, height, depth, border, imageSize, data); 3668 3669 if (target == GL_TEXTURE_3D) { 3670 /* non-proxy target */ 3671 struct gl_texture_object *texObj; 3672 struct gl_texture_image *texImage; 3673 GLenum error = compressed_texture_error_check(ctx, 3, target, level, 3674 internalFormat, width, height, depth, border, imageSize); 3675 if (error) { 3676 _mesa_error(ctx, error, "glCompressedTexImage3D"); 3677 return; 3678 } 3679 3680 texObj = _mesa_get_current_tex_object(ctx, target); 3681 3682 _mesa_lock_texture(ctx, texObj); 3683 { 3684 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 3685 if (!texImage) { 3686 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D"); 3687 } 3688 else { 3689 if (texImage->Data) { 3690 ctx->Driver.FreeTexImageData( ctx, texImage ); 3691 } 3692 ASSERT(texImage->Data == NULL); 3693 3694 _mesa_init_teximage_fields(ctx, target, texImage, 3695 width, height, depth, 3696 border, internalFormat); 3697 3698 /* Choose actual texture format */ 3699 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 3700 internalFormat, GL_NONE, GL_NONE); 3701 3702 ASSERT(ctx->Driver.CompressedTexImage3D); 3703 ctx->Driver.CompressedTexImage3D(ctx, target, level, 3704 internalFormat, 3705 width, height, depth, 3706 border, imageSize, data, 3707 texObj, texImage); 3708 3709 _mesa_set_fetch_functions(texImage, 3); 3710 3711 check_gen_mipmap(ctx, target, texObj, level); 3712 3713 /* state update */ 3714 texObj->_Complete = GL_FALSE; 3715 ctx->NewState |= _NEW_TEXTURE; 3716 } 3717 } 3718 _mesa_unlock_texture(ctx, texObj); 3719 } 3720 else if (target == GL_PROXY_TEXTURE_3D) { 3721 /* Proxy texture: check for errors and update proxy state */ 3722 GLenum error = compressed_texture_error_check(ctx, 3, target, level, 3723 internalFormat, width, height, depth, border, imageSize); 3724 if (!error) { 3725 ASSERT(ctx->Driver.TestProxyTexImage); 3726 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 3727 internalFormat, GL_NONE, GL_NONE, 3728 width, height, depth, border); 3729 } 3730 if (error) { 3731 /* if error, clear all proxy texture image parameters */ 3732 struct gl_texture_image *texImage; 3733 texImage = _mesa_get_proxy_tex_image(ctx, target, level); 3734 if (texImage) 3735 clear_teximage_fields(texImage); 3736 } 3737 else { 3738 /* store the teximage parameters */ 3739 struct gl_texture_object *texObj; 3740 struct gl_texture_image *texImage; 3741 3742 texObj = _mesa_get_current_tex_object(ctx, target); 3743 3744 _mesa_lock_texture(ctx, texObj); 3745 { 3746 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3747 _mesa_init_teximage_fields(ctx, target, texImage, width, height, 3748 depth, border, internalFormat); 3749 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 3750 internalFormat, GL_NONE, GL_NONE); 3751 } 3752 _mesa_unlock_texture(ctx, texObj); 3753 } 3754 } 3755 else { 3756 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3D(target)"); 3757 return; 3758 } 3759} 3760 3761 3762/** 3763 * Common helper for glCompressedTexSubImage1/2/3D(). 3764 */ 3765static void 3766compressed_tex_sub_image(GLuint dims, GLenum target, GLint level, 3767 GLint xoffset, GLint yoffset, GLint zoffset, 3768 GLsizei width, GLsizei height, GLsizei depth, 3769 GLenum format, GLsizei imageSize, const GLvoid *data) 3770{ 3771 struct gl_texture_object *texObj; 3772 struct gl_texture_image *texImage; 3773 GLenum error; 3774 GET_CURRENT_CONTEXT(ctx); 3775 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3776 3777 error = compressed_subtexture_error_check(ctx, dims, target, level, 3778 xoffset, 0, 0, /* pos */ 3779 width, height, depth, /* size */ 3780 format, imageSize); 3781 if (error) { 3782 _mesa_error(ctx, error, "glCompressedTexSubImage%uD", dims); 3783 return; 3784 } 3785 3786 texObj = _mesa_get_current_tex_object(ctx, target); 3787 3788 _mesa_lock_texture(ctx, texObj); 3789 { 3790 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3791 assert(texImage); 3792 3793 if (compressed_subtexture_error_check2(ctx, dims, width, height, depth, 3794 format, texImage)) { 3795 /* error was recorded */ 3796 } 3797 else if (width > 0 && height > 0 && depth > 0) { 3798 switch (dims) { 3799 case 1: 3800 if (ctx->Driver.CompressedTexSubImage1D) { 3801 ctx->Driver.CompressedTexSubImage1D(ctx, target, level, 3802 xoffset, width, 3803 format, imageSize, data, 3804 texObj, texImage); 3805 } 3806 break; 3807 case 2: 3808 if (ctx->Driver.CompressedTexSubImage2D) { 3809 ctx->Driver.CompressedTexSubImage2D(ctx, target, level, 3810 xoffset, yoffset, 3811 width, height, 3812 format, imageSize, data, 3813 texObj, texImage); 3814 } 3815 break; 3816 case 3: 3817 if (ctx->Driver.CompressedTexSubImage3D) { 3818 ctx->Driver.CompressedTexSubImage3D(ctx, target, level, 3819 xoffset, yoffset, zoffset, 3820 width, height, depth, 3821 format, imageSize, data, 3822 texObj, texImage); 3823 } 3824 break; 3825 default: 3826 ; 3827 } 3828 3829 check_gen_mipmap(ctx, target, texObj, level); 3830 3831 ctx->NewState |= _NEW_TEXTURE; 3832 } 3833 } 3834 _mesa_unlock_texture(ctx, texObj); 3835} 3836 3837 3838void GLAPIENTRY 3839_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, 3840 GLsizei width, GLenum format, 3841 GLsizei imageSize, const GLvoid *data) 3842{ 3843 compressed_tex_sub_image(1, target, level, xoffset, 0, 0, width, 1, 1, 3844 format, imageSize, data); 3845} 3846 3847 3848void GLAPIENTRY 3849_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, 3850 GLint yoffset, GLsizei width, GLsizei height, 3851 GLenum format, GLsizei imageSize, 3852 const GLvoid *data) 3853{ 3854 compressed_tex_sub_image(2, target, level, xoffset, yoffset, 0, 3855 width, height, 1, format, imageSize, data); 3856} 3857 3858 3859void GLAPIENTRY 3860_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, 3861 GLint yoffset, GLint zoffset, GLsizei width, 3862 GLsizei height, GLsizei depth, GLenum format, 3863 GLsizei imageSize, const GLvoid *data) 3864{ 3865 compressed_tex_sub_image(3, target, level, xoffset, yoffset, zoffset, 3866 width, height, depth, format, imageSize, data); 3867} 3868