teximage.c revision 16a8e986cebae6560d00992b6b9f54549e1d03c6
130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/* $Id: teximage.c,v 1.89 2001/03/28 21:36:31 gareth Exp $ */ 230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng 330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/* 430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * Mesa 3-D graphics library 530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * Version: 3.5 630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * 730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. 830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * 930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * Permission is hereby granted, free of charge, to any person obtaining a 1030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * copy of this software and associated documentation files (the "Software"), 1130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * to deal in the Software without restriction, including without limitation 1230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * and/or sell copies of the Software, and to permit persons to whom the 1430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * Software is furnished to do so, subject to the following conditions: 1530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * 1630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * The above copyright notice and this permission notice shall be included 1730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * in all copies or substantial portions of the Software. 1830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * 1930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 2030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng */ 2630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng 2730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng 2830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#ifdef PC_HEADER 2930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "all.h" 3030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#else 3130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "glheader.h" 3230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "context.h" 3330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "convolve.h" 3430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "image.h" 3530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "macros.h" 3630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "mem.h" 3730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "mmath.h" 3830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "state.h" 3930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "texformat.h" 4030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "teximage.h" 4130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "texstate.h" 4230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "mtypes.h" 4330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "swrast/s_span.h" /* XXX SWRAST hack */ 4430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#endif 4530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng 4630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng 4730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/* 4830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * NOTES: 4930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * 5030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * Mesa's native texture datatype is GLchan. Native formats are 5130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA, 5230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * and GL_COLOR_INDEX. 5330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * Device drivers are free to implement any internal format they want. 5430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng */ 5530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng 5630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng 5730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#ifdef DEBUG 5830692c65c4174412c90e79489e98ab85c1a7412fBen Chengstatic void PrintTexture(const struct gl_texture_image *img) 5930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng{ 6030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng GLuint i, j, c; 6130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng const GLchan *data = (const GLchan *) img->Data; 6230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng 6330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng if (!data) { 6430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng printf("No texture data\n"); 6530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng return; 6630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng } 6730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng 6830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng switch (img->Format) { 6930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng case GL_ALPHA: 7030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng case GL_LUMINANCE: 7130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng case GL_INTENSITY: 7230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng case GL_COLOR_INDEX: 7330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng c = 1; 7430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng break; 7530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng case GL_LUMINANCE_ALPHA: 7630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng c = 2; 7730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng break; 7830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng case GL_RGB: 7930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng c = 3; 8030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng break; 8130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng case GL_RGBA: 8230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng c = 4; 8330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng break; 8430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng default: 8530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng _mesa_problem(NULL, "error in PrintTexture\n"); 8630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng return; 8730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng } 8830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng 8930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng for (i = 0; i < img->Height; i++) { 9030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng for (j = 0; j < img->Width; j++) { 9130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng if (c==1) 9230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng printf("%02x ", data[0]); 9330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng else if (c==2) 9430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng printf("%02x%02x ", data[0], data[1]); 9530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng else if (c==3) 9630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng printf("%02x%02x%02x ", data[0], data[1], data[2]); 9730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng else if (c==4) 9830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng printf("%02x%02x%02x%02x ", data[0], data[1], data[2], data[3]); 9930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng data += c; 10030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng } 10130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng printf("\n"); 10230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng } 10330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng} 10430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#endif 10530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng 10630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng 10730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng 10830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/* 10930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * Compute log base 2 of n. 11030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * If n isn't an exact power of two return -1. 11130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng * If n < 0 return -1. 11230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng */ 11330692c65c4174412c90e79489e98ab85c1a7412fBen Chengstatic int 11430692c65c4174412c90e79489e98ab85c1a7412fBen Chenglogbase2( int n ) 11530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng{ 11630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng GLint i = 1; 11730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng GLint log2 = 0; 118 119 if (n < 0) { 120 return -1; 121 } 122 123 while ( n > i ) { 124 i *= 2; 125 log2++; 126 } 127 if (i != n) { 128 return -1; 129 } 130 else { 131 return log2; 132 } 133} 134 135 136 137/* 138 * Given an internal texture format enum or 1, 2, 3, 4 return the 139 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE, 140 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. 141 * Return -1 if invalid enum. 142 */ 143GLint 144_mesa_base_tex_format( GLcontext *ctx, GLint format ) 145{ 146 /* 147 * Ask the driver for the base format, if it doesn't 148 * know, it will return -1; 149 */ 150 if (ctx->Driver.BaseCompressedTexFormat) { 151 GLint ifmt = (*ctx->Driver.BaseCompressedTexFormat)(ctx, format); 152 if (ifmt >= 0) { 153 return ifmt; 154 } 155 } 156 switch (format) { 157 case GL_ALPHA: 158 case GL_ALPHA4: 159 case GL_ALPHA8: 160 case GL_ALPHA12: 161 case GL_ALPHA16: 162 return GL_ALPHA; 163 case 1: 164 case GL_LUMINANCE: 165 case GL_LUMINANCE4: 166 case GL_LUMINANCE8: 167 case GL_LUMINANCE12: 168 case GL_LUMINANCE16: 169 return GL_LUMINANCE; 170 case 2: 171 case GL_LUMINANCE_ALPHA: 172 case GL_LUMINANCE4_ALPHA4: 173 case GL_LUMINANCE6_ALPHA2: 174 case GL_LUMINANCE8_ALPHA8: 175 case GL_LUMINANCE12_ALPHA4: 176 case GL_LUMINANCE12_ALPHA12: 177 case GL_LUMINANCE16_ALPHA16: 178 return GL_LUMINANCE_ALPHA; 179 case GL_INTENSITY: 180 case GL_INTENSITY4: 181 case GL_INTENSITY8: 182 case GL_INTENSITY12: 183 case GL_INTENSITY16: 184 return GL_INTENSITY; 185 case 3: 186 case GL_RGB: 187 case GL_R3_G3_B2: 188 case GL_RGB4: 189 case GL_RGB5: 190 case GL_RGB8: 191 case GL_RGB10: 192 case GL_RGB12: 193 case GL_RGB16: 194 return GL_RGB; 195 case 4: 196 case GL_RGBA: 197 case GL_RGBA2: 198 case GL_RGBA4: 199 case GL_RGB5_A1: 200 case GL_RGBA8: 201 case GL_RGB10_A2: 202 case GL_RGBA12: 203 case GL_RGBA16: 204 return GL_RGBA; 205 case GL_COLOR_INDEX: 206 case GL_COLOR_INDEX1_EXT: 207 case GL_COLOR_INDEX2_EXT: 208 case GL_COLOR_INDEX4_EXT: 209 case GL_COLOR_INDEX8_EXT: 210 case GL_COLOR_INDEX12_EXT: 211 case GL_COLOR_INDEX16_EXT: 212 return GL_COLOR_INDEX; 213 case GL_DEPTH_COMPONENT: 214 case GL_DEPTH_COMPONENT16_SGIX: 215 case GL_DEPTH_COMPONENT24_SGIX: 216 case GL_DEPTH_COMPONENT32_SGIX: 217 if (ctx->Extensions.SGIX_depth_texture) 218 return GL_DEPTH_COMPONENT; 219 else 220 return -1; 221 default: 222 return -1; /* error */ 223 } 224} 225 226 227/* 228 * Test if the given image format is a color/rgba format. That is, 229 * not color index, depth, stencil, etc. 230 */ 231static GLboolean 232is_color_format(GLenum format) 233{ 234 switch (format) { 235 case GL_ALPHA: 236 case GL_ALPHA4: 237 case GL_ALPHA8: 238 case GL_ALPHA12: 239 case GL_ALPHA16: 240 case 1: 241 case GL_LUMINANCE: 242 case GL_LUMINANCE4: 243 case GL_LUMINANCE8: 244 case GL_LUMINANCE12: 245 case GL_LUMINANCE16: 246 case 2: 247 case GL_LUMINANCE_ALPHA: 248 case GL_LUMINANCE4_ALPHA4: 249 case GL_LUMINANCE6_ALPHA2: 250 case GL_LUMINANCE8_ALPHA8: 251 case GL_LUMINANCE12_ALPHA4: 252 case GL_LUMINANCE12_ALPHA12: 253 case GL_LUMINANCE16_ALPHA16: 254 case GL_INTENSITY: 255 case GL_INTENSITY4: 256 case GL_INTENSITY8: 257 case GL_INTENSITY12: 258 case GL_INTENSITY16: 259 case 3: 260 case GL_RGB: 261 case GL_R3_G3_B2: 262 case GL_RGB4: 263 case GL_RGB5: 264 case GL_RGB8: 265 case GL_RGB10: 266 case GL_RGB12: 267 case GL_RGB16: 268 case 4: 269 case GL_RGBA: 270 case GL_RGBA2: 271 case GL_RGBA4: 272 case GL_RGB5_A1: 273 case GL_RGBA8: 274 case GL_RGB10_A2: 275 case GL_RGBA12: 276 case GL_RGBA16: 277 return GL_TRUE; 278 default: 279 return GL_FALSE; 280 } 281} 282 283 284static GLboolean 285is_index_format(GLenum format) 286{ 287 switch (format) { 288 case GL_COLOR_INDEX: 289 case GL_COLOR_INDEX1_EXT: 290 case GL_COLOR_INDEX2_EXT: 291 case GL_COLOR_INDEX4_EXT: 292 case GL_COLOR_INDEX8_EXT: 293 case GL_COLOR_INDEX12_EXT: 294 case GL_COLOR_INDEX16_EXT: 295 return GL_TRUE; 296 default: 297 return GL_FALSE; 298 } 299} 300 301 302/* 303 * Return GL_TRUE if internalFormat is a compressed format, return GL_FALSE 304 * otherwise. 305 */ 306static GLboolean 307is_compressed_format(GLcontext *ctx, GLenum internalFormat) 308{ 309 if (ctx->Driver.IsCompressedFormat) { 310 return (*ctx->Driver.IsCompressedFormat)(ctx, internalFormat); 311 } 312 return GL_FALSE; 313} 314 315 316 317/* 318 * Store a gl_texture_image pointer in a gl_texture_object structure 319 * according to the target and level parameters. 320 * This was basically prompted by the introduction of cube maps. 321 */ 322static void 323set_tex_image(struct gl_texture_object *tObj, 324 GLenum target, GLint level, 325 struct gl_texture_image *texImage) 326{ 327 ASSERT(tObj); 328 ASSERT(texImage); 329 switch (target) { 330 case GL_TEXTURE_2D: 331 tObj->Image[level] = texImage; 332 return; 333 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 334 tObj->Image[level] = texImage; 335 return; 336 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 337 tObj->NegX[level] = texImage; 338 return; 339 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 340 tObj->PosY[level] = texImage; 341 return; 342 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 343 tObj->NegY[level] = texImage; 344 return; 345 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 346 tObj->PosZ[level] = texImage; 347 return; 348 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 349 tObj->NegZ[level] = texImage; 350 return; 351 default: 352 _mesa_problem(NULL, "bad target in set_tex_image()"); 353 return; 354 } 355} 356 357 358 359/* 360 * Return new gl_texture_image struct with all fields initialized to zero. 361 */ 362struct gl_texture_image * 363_mesa_alloc_texture_image( void ) 364{ 365 return CALLOC_STRUCT(gl_texture_image); 366} 367 368 369 370void 371_mesa_free_texture_image( struct gl_texture_image *teximage ) 372{ 373 if (teximage->Data) { 374 FREE( teximage->Data ); 375 teximage->Data = NULL; 376 } 377 FREE( teximage ); 378} 379 380 381/* 382 * Return GL_TRUE if the target is a proxy target. 383 */ 384static GLboolean 385is_proxy_target(GLenum target) 386{ 387 return (target == GL_PROXY_TEXTURE_1D || 388 target == GL_PROXY_TEXTURE_2D || 389 target == GL_PROXY_TEXTURE_3D || 390 target == GL_PROXY_TEXTURE_CUBE_MAP_ARB); 391} 392 393 394/* 395 * Given a texture unit and a texture target, return the corresponding 396 * texture object. 397 */ 398struct gl_texture_object * 399_mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit, 400 GLenum target) 401{ 402 switch (target) { 403 case GL_TEXTURE_1D: 404 return texUnit->Current1D; 405 case GL_PROXY_TEXTURE_1D: 406 return ctx->Texture.Proxy1D; 407 case GL_TEXTURE_2D: 408 return texUnit->Current2D; 409 case GL_PROXY_TEXTURE_2D: 410 return ctx->Texture.Proxy2D; 411 case GL_TEXTURE_3D: 412 return texUnit->Current3D; 413 case GL_PROXY_TEXTURE_3D: 414 return ctx->Texture.Proxy3D; 415 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 416 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 417 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 418 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 419 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 420 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 421 return ctx->Extensions.ARB_texture_cube_map 422 ? texUnit->CurrentCubeMap : NULL; 423 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 424 return ctx->Extensions.ARB_texture_cube_map 425 ? ctx->Texture.ProxyCubeMap : NULL; 426 default: 427 _mesa_problem(NULL, "bad target in _mesa_select_tex_object()"); 428 return NULL; 429 } 430} 431 432 433/* 434 * Return the texture image struct which corresponds to target and level 435 * for the given texture unit. 436 */ 437struct gl_texture_image * 438_mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, 439 GLenum target, GLint level) 440{ 441 ASSERT(texUnit); 442 switch (target) { 443 case GL_TEXTURE_1D: 444 return texUnit->Current1D->Image[level]; 445 case GL_PROXY_TEXTURE_1D: 446 return ctx->Texture.Proxy1D->Image[level]; 447 case GL_TEXTURE_2D: 448 return texUnit->Current2D->Image[level]; 449 case GL_PROXY_TEXTURE_2D: 450 return ctx->Texture.Proxy2D->Image[level]; 451 case GL_TEXTURE_3D: 452 return texUnit->Current3D->Image[level]; 453 case GL_PROXY_TEXTURE_3D: 454 return ctx->Texture.Proxy3D->Image[level]; 455 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 456 if (ctx->Extensions.ARB_texture_cube_map) 457 return texUnit->CurrentCubeMap->Image[level]; 458 else 459 return NULL; 460 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 461 if (ctx->Extensions.ARB_texture_cube_map) 462 return texUnit->CurrentCubeMap->NegX[level]; 463 else 464 return NULL; 465 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 466 if (ctx->Extensions.ARB_texture_cube_map) 467 return texUnit->CurrentCubeMap->PosY[level]; 468 else 469 return NULL; 470 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 471 if (ctx->Extensions.ARB_texture_cube_map) 472 return texUnit->CurrentCubeMap->NegY[level]; 473 else 474 return NULL; 475 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 476 if (ctx->Extensions.ARB_texture_cube_map) 477 return texUnit->CurrentCubeMap->PosZ[level]; 478 else 479 return NULL; 480 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 481 if (ctx->Extensions.ARB_texture_cube_map) 482 return texUnit->CurrentCubeMap->NegZ[level]; 483 else 484 return NULL; 485 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 486 if (ctx->Extensions.ARB_texture_cube_map) 487 return ctx->Texture.ProxyCubeMap->Image[level]; 488 else 489 return NULL; 490 default: 491 _mesa_problem(ctx, "bad target in _mesa_select_tex_image()"); 492 return NULL; 493 } 494} 495 496 497 498/* 499 * glTexImage[123]D can accept a NULL image pointer. In this case we 500 * create a texture image with unspecified image contents per the OpenGL 501 * spec. 502 */ 503static GLubyte * 504make_null_texture(GLint width, GLint height, GLint depth, GLenum format) 505{ 506 const GLint components = _mesa_components_in_format(format); 507 const GLint numPixels = width * height * depth; 508 GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte)); 509 510 /* 511 * Let's see if anyone finds this. If glTexImage2D() is called with 512 * a NULL image pointer then load the texture image with something 513 * interesting instead of leaving it indeterminate. 514 */ 515 if (data) { 516 static const char message[8][32] = { 517 " X X XXXXX XXX X ", 518 " XX XX X X X X X ", 519 " X X X X X X X ", 520 " X X XXXX XXX XXXXX ", 521 " X X X X X X ", 522 " X X X X X X X ", 523 " X X XXXXX XXX X X ", 524 " " 525 }; 526 527 GLubyte *imgPtr = data; 528 GLint h, i, j, k; 529 for (h = 0; h < depth; h++) { 530 for (i = 0; i < height; i++) { 531 GLint srcRow = 7 - (i % 8); 532 for (j = 0; j < width; j++) { 533 GLint srcCol = j % 32; 534 GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70; 535 for (k = 0; k < components; k++) { 536 *imgPtr++ = texel; 537 } 538 } 539 } 540 } 541 } 542 543 return data; 544} 545 546 547 548/* 549 * Reset the fields of a gl_texture_image struct to zero. 550 * This is called when a proxy texture test fails, we set all the 551 * image members (except DriverData) to zero. 552 * It's also used in glTexImage[123]D as a safeguard to be sure all 553 * required fields get initialized properly by the Driver.TexImage[123]D 554 * functions. 555 */ 556static void 557clear_teximage_fields(struct gl_texture_image *img) 558{ 559 ASSERT(img); 560 img->Format = 0; 561 img->IntFormat = 0; 562 img->Border = 0; 563 img->Width = 0; 564 img->Height = 0; 565 img->Depth = 0; 566 img->Width2 = 0; 567 img->Height2 = 0; 568 img->Depth2 = 0; 569 img->WidthLog2 = 0; 570 img->HeightLog2 = 0; 571 img->DepthLog2 = 0; 572 img->Data = NULL; 573 img->TexFormat = &_mesa_null_texformat; 574 img->FetchTexel = NULL; 575 img->IsCompressed = 0; 576 img->CompressedSize = 0; 577} 578 579 580/* 581 * Initialize basic fields of the gl_texture_image struct. 582 */ 583static void 584init_teximage_fields(GLcontext *ctx, 585 struct gl_texture_image *img, 586 GLsizei width, GLsizei height, GLsizei depth, 587 GLint border, GLenum internalFormat) 588{ 589 ASSERT(img); 590 img->Format = _mesa_base_tex_format( ctx, internalFormat ); 591 img->IntFormat = internalFormat; 592 img->Border = border; 593 img->Width = width; 594 img->Height = height; 595 img->Depth = depth; 596 img->WidthLog2 = logbase2(width - 2 * border); 597 if (height == 1) /* 1-D texture */ 598 img->HeightLog2 = 0; 599 else 600 img->HeightLog2 = logbase2(height - 2 * border); 601 if (depth == 1) /* 2-D texture */ 602 img->DepthLog2 = 0; 603 else 604 img->DepthLog2 = logbase2(depth - 2 * border); 605 img->Width2 = 1 << img->WidthLog2; 606 img->Height2 = 1 << img->HeightLog2; 607 img->Depth2 = 1 << img->DepthLog2; 608 img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); 609 img->IsCompressed = is_compressed_format(ctx, internalFormat); 610} 611 612 613 614/* 615 * Test glTexImage[123]D() parameters for errors. 616 * Input: 617 * dimensions - must be 1 or 2 or 3 618 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors 619 */ 620static GLboolean 621texture_error_check( GLcontext *ctx, GLenum target, 622 GLint level, GLint internalFormat, 623 GLenum format, GLenum type, 624 GLuint dimensions, 625 GLint width, GLint height, 626 GLint depth, GLint border ) 627{ 628 GLboolean isProxy; 629 GLint iformat; 630 631 if (dimensions == 1) { 632 isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_1D); 633 if (target != GL_TEXTURE_1D && !isProxy) { 634 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" ); 635 return GL_TRUE; 636 } 637 } 638 else if (dimensions == 2) { 639 isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_2D || 640 target == GL_PROXY_TEXTURE_CUBE_MAP_ARB); 641 if (target != GL_TEXTURE_2D && !isProxy && 642 !(ctx->Extensions.ARB_texture_cube_map && 643 target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 644 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { 645 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" ); 646 return GL_TRUE; 647 } 648 } 649 else if (dimensions == 3) { 650 isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_3D); 651 if (target != GL_TEXTURE_3D && !isProxy) { 652 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" ); 653 return GL_TRUE; 654 } 655 } 656 else { 657 _mesa_problem( ctx, "bad dims in texture_error_check" ); 658 return GL_TRUE; 659 } 660 661 /* Border */ 662 if (border != 0 && border != 1) { 663 if (!isProxy) { 664 char message[100]; 665 sprintf(message, "glTexImage%dD(border=%d)", dimensions, border); 666 _mesa_error(ctx, GL_INVALID_VALUE, message); 667 } 668 return GL_TRUE; 669 } 670 671 /* Width */ 672 if (width < 2 * border || width > 2 + ctx->Const.MaxTextureSize 673 || logbase2( width - 2 * border ) < 0) { 674 if (!isProxy) { 675 char message[100]; 676 sprintf(message, "glTexImage%dD(width=%d)", dimensions, width); 677 _mesa_error(ctx, GL_INVALID_VALUE, message); 678 } 679 return GL_TRUE; 680 } 681 682 /* Height */ 683 if (dimensions >= 2) { 684 if (height < 2 * border || height > 2 + ctx->Const.MaxTextureSize 685 || logbase2( height - 2 * border ) < 0) { 686 if (!isProxy) { 687 char message[100]; 688 sprintf(message, "glTexImage%dD(height=%d)", dimensions, height); 689 _mesa_error(ctx, GL_INVALID_VALUE, message); 690 } 691 return GL_TRUE; 692 } 693 } 694 695 /* For cube map, width must equal height */ 696 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 697 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 698 if (width != height) { 699 if (!isProxy) { 700 _mesa_error(ctx, GL_INVALID_VALUE, "glTexImage2D(width != height)"); 701 } 702 return GL_TRUE; 703 } 704 } 705 706 /* Depth */ 707 if (dimensions >= 3) { 708 if (depth < 2 * border || depth > 2 + ctx->Const.MaxTextureSize 709 || logbase2( depth - 2 * border ) < 0) { 710 if (!isProxy) { 711 char message[100]; 712 sprintf(message, "glTexImage3D(depth=%d)", depth ); 713 _mesa_error( ctx, GL_INVALID_VALUE, message ); 714 } 715 return GL_TRUE; 716 } 717 } 718 719 /* Level */ 720 if (level < 0 || level >= ctx->Const.MaxTextureLevels) { 721 if (!isProxy) { 722 char message[100]; 723 sprintf(message, "glTexImage%dD(level=%d)", dimensions, level); 724 _mesa_error(ctx, GL_INVALID_VALUE, message); 725 } 726 return GL_TRUE; 727 } 728 729 /* For cube map, width must equal height */ 730 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 731 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 732 if (width != height) { 733 _mesa_error(ctx, GL_INVALID_VALUE, "glTexImage2D(width != height)"); 734 return GL_TRUE; 735 } 736 } 737 738 iformat = _mesa_base_tex_format( ctx, internalFormat ); 739 if (iformat < 0) { 740 if (!isProxy) { 741 char message[100]; 742 sprintf(message, "glTexImage%dD(internalFormat=0x%x)", dimensions, 743 internalFormat); 744 _mesa_error(ctx, GL_INVALID_VALUE, message); 745 } 746 return GL_TRUE; 747 } 748 749 if (!is_compressed_format( ctx, internalFormat ) && 750 !_mesa_is_legal_format_and_type( format, type )) { 751 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there 752 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4. 753 */ 754 if (!isProxy) { 755 char message[100]; 756 sprintf(message, "glTexImage%dD(format or type)", dimensions); 757 _mesa_error(ctx, GL_INVALID_OPERATION, message); 758 } 759 return GL_TRUE; 760 } 761 762 /* if we get here, the parameters are OK */ 763 return GL_FALSE; 764} 765 766 767 768/* 769 * Test glTexSubImage[123]D() parameters for errors. 770 * Input: 771 * dimensions - must be 1 or 2 or 3 772 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors 773 */ 774static GLboolean 775subtexture_error_check( GLcontext *ctx, GLuint dimensions, 776 GLenum target, GLint level, 777 GLint xoffset, GLint yoffset, GLint zoffset, 778 GLint width, GLint height, GLint depth, 779 GLenum format, GLenum type ) 780{ 781 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 782 struct gl_texture_image *destTex; 783 784 if (dimensions == 1) { 785 if (target != GL_TEXTURE_1D) { 786 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" ); 787 return GL_TRUE; 788 } 789 } 790 else if (dimensions == 2) { 791 if (ctx->Extensions.ARB_texture_cube_map) { 792 if ((target < GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || 793 target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) && 794 target != GL_TEXTURE_2D) { 795 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); 796 return GL_TRUE; 797 } 798 } 799 else if (target != GL_TEXTURE_2D) { 800 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); 801 return GL_TRUE; 802 } 803 } 804 else if (dimensions == 3) { 805 if (target != GL_TEXTURE_3D) { 806 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" ); 807 return GL_TRUE; 808 } 809 } 810 else { 811 _mesa_problem( ctx, "bad dims in texture_error_check" ); 812 return GL_TRUE; 813 } 814 815 if (level < 0 || level >= ctx->Const.MaxTextureLevels) { 816 char message[100]; 817 sprintf(message, "glTexSubImage2D(level=%d)", level); 818 _mesa_error(ctx, GL_INVALID_ENUM, message); 819 return GL_TRUE; 820 } 821 822 if (width < 0) { 823 char message[100]; 824 sprintf(message, "glTexSubImage%dD(width=%d)", dimensions, width); 825 _mesa_error(ctx, GL_INVALID_VALUE, message); 826 return GL_TRUE; 827 } 828 if (height < 0 && dimensions > 1) { 829 char message[100]; 830 sprintf(message, "glTexSubImage%dD(height=%d)", dimensions, height); 831 _mesa_error(ctx, GL_INVALID_VALUE, message); 832 return GL_TRUE; 833 } 834 if (depth < 0 && dimensions > 2) { 835 char message[100]; 836 sprintf(message, "glTexSubImage%dD(depth=%d)", dimensions, depth); 837 _mesa_error(ctx, GL_INVALID_VALUE, message); 838 return GL_TRUE; 839 } 840 841 destTex = _mesa_select_tex_image(ctx, texUnit, target, level); 842 843 if (!destTex) { 844 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage2D"); 845 return GL_TRUE; 846 } 847 848 if (xoffset < -((GLint)destTex->Border)) { 849 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage1/2/3D(xoffset)"); 850 return GL_TRUE; 851 } 852 if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) { 853 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage1/2/3D(xoffset+width)"); 854 return GL_TRUE; 855 } 856 if (dimensions > 1) { 857 if (yoffset < -((GLint)destTex->Border)) { 858 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage2/3D(yoffset)"); 859 return GL_TRUE; 860 } 861 if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) { 862 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage2/3D(yoffset+height)"); 863 return GL_TRUE; 864 } 865 } 866 if (dimensions > 2) { 867 if (zoffset < -((GLint)destTex->Border)) { 868 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)"); 869 return GL_TRUE; 870 } 871 if (zoffset + depth > (GLint) (destTex->Depth + destTex->Border)) { 872 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)"); 873 return GL_TRUE; 874 } 875 } 876 877 if (!is_compressed_format(ctx, destTex->IntFormat) && 878 !_mesa_is_legal_format_and_type(format, type)) { 879 char message[100]; 880 sprintf(message, "glTexSubImage%dD(format or type)", dimensions); 881 _mesa_error(ctx, GL_INVALID_ENUM, message); 882 return GL_TRUE; 883 } 884 885 return GL_FALSE; 886} 887 888 889/* 890 * Test glCopyTexImage[12]D() parameters for errors. 891 * Input: dimensions - must be 1 or 2 or 3 892 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors 893 */ 894static GLboolean 895copytexture_error_check( GLcontext *ctx, GLuint dimensions, 896 GLenum target, GLint level, GLint internalFormat, 897 GLint width, GLint height, GLint border ) 898{ 899 GLint iformat; 900 901 if (dimensions == 1) { 902 if (target != GL_TEXTURE_1D) { 903 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" ); 904 return GL_TRUE; 905 } 906 } 907 else if (dimensions == 2) { 908 if (ctx->Extensions.ARB_texture_cube_map) { 909 if ((target < GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || 910 target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) && 911 target != GL_TEXTURE_2D) { 912 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); 913 return GL_TRUE; 914 } 915 } 916 else if (target != GL_TEXTURE_2D) { 917 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); 918 return GL_TRUE; 919 } 920 } 921 922 /* Border */ 923 if (border != 0 && border != 1) { 924 char message[100]; 925 sprintf(message, "glCopyTexImage%dD(border)", dimensions); 926 _mesa_error(ctx, GL_INVALID_VALUE, message); 927 return GL_TRUE; 928 } 929 930 /* Width */ 931 if (width < 2 * border || width > 2 + ctx->Const.MaxTextureSize 932 || logbase2( width - 2 * border ) < 0) { 933 char message[100]; 934 sprintf(message, "glCopyTexImage%dD(width=%d)", dimensions, width); 935 _mesa_error(ctx, GL_INVALID_VALUE, message); 936 return GL_TRUE; 937 } 938 939 /* Height */ 940 if (dimensions >= 2) { 941 if (height < 2 * border || height > 2 + ctx->Const.MaxTextureSize 942 || logbase2( height - 2 * border ) < 0) { 943 char message[100]; 944 sprintf(message, "glCopyTexImage%dD(height=%d)", dimensions, height); 945 _mesa_error(ctx, GL_INVALID_VALUE, message); 946 return GL_TRUE; 947 } 948 } 949 950 /* For cube map, width must equal height */ 951 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 952 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 953 if (width != height) { 954 _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexImage2D(width != height)"); 955 return GL_TRUE; 956 } 957 } 958 959 /* Level */ 960 if (level < 0 || level>=ctx->Const.MaxTextureLevels) { 961 char message[100]; 962 sprintf(message, "glCopyTexImage%dD(level=%d)", dimensions, level); 963 _mesa_error(ctx, GL_INVALID_VALUE, message); 964 return GL_TRUE; 965 } 966 967 iformat = _mesa_base_tex_format( ctx, internalFormat ); 968 if (iformat < 0) { 969 char message[100]; 970 sprintf(message, "glCopyTexImage%dD(internalFormat)", dimensions); 971 _mesa_error(ctx, GL_INVALID_VALUE, message); 972 return GL_TRUE; 973 } 974 975 /* if we get here, the parameters are OK */ 976 return GL_FALSE; 977} 978 979 980static GLboolean 981copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, 982 GLenum target, GLint level, 983 GLint xoffset, GLint yoffset, GLint zoffset, 984 GLsizei width, GLsizei height ) 985{ 986 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 987 struct gl_texture_image *teximage; 988 989 if (dimensions == 1) { 990 if (target != GL_TEXTURE_1D) { 991 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" ); 992 return GL_TRUE; 993 } 994 } 995 else if (dimensions == 2) { 996 if (ctx->Extensions.ARB_texture_cube_map) { 997 if ((target < GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || 998 target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) && 999 target != GL_TEXTURE_2D) { 1000 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); 1001 return GL_TRUE; 1002 } 1003 } 1004 else if (target != GL_TEXTURE_2D) { 1005 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); 1006 return GL_TRUE; 1007 } 1008 } 1009 else if (dimensions == 3) { 1010 if (target != GL_TEXTURE_3D) { 1011 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" ); 1012 return GL_TRUE; 1013 } 1014 } 1015 1016 if (level < 0 || level >= ctx->Const.MaxTextureLevels) { 1017 char message[100]; 1018 sprintf(message, "glCopyTexSubImage%dD(level=%d)", dimensions, level); 1019 _mesa_error(ctx, GL_INVALID_VALUE, message); 1020 return GL_TRUE; 1021 } 1022 1023 if (width < 0) { 1024 char message[100]; 1025 sprintf(message, "glCopyTexSubImage%dD(width=%d)", dimensions, width); 1026 _mesa_error(ctx, GL_INVALID_VALUE, message); 1027 return GL_TRUE; 1028 } 1029 if (dimensions > 1 && height < 0) { 1030 char message[100]; 1031 sprintf(message, "glCopyTexSubImage%dD(height=%d)", dimensions, height); 1032 _mesa_error(ctx, GL_INVALID_VALUE, message); 1033 return GL_TRUE; 1034 } 1035 1036 teximage = _mesa_select_tex_image(ctx, texUnit, target, level); 1037 if (!teximage) { 1038 char message[100]; 1039 sprintf(message, "glCopyTexSubImage%dD(undefined texture)", dimensions); 1040 _mesa_error(ctx, GL_INVALID_OPERATION, message); 1041 return GL_TRUE; 1042 } 1043 1044 if (xoffset < -((GLint)teximage->Border)) { 1045 char message[100]; 1046 sprintf(message, "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset); 1047 _mesa_error(ctx, GL_INVALID_VALUE, message); 1048 return GL_TRUE; 1049 } 1050 if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) { 1051 char message[100]; 1052 sprintf(message, "glCopyTexSubImage%dD(xoffset+width)", dimensions); 1053 _mesa_error(ctx, GL_INVALID_VALUE, message); 1054 return GL_TRUE; 1055 } 1056 if (dimensions > 1) { 1057 if (yoffset < -((GLint)teximage->Border)) { 1058 char message[100]; 1059 sprintf(message, "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset); 1060 _mesa_error(ctx, GL_INVALID_VALUE, message); 1061 return GL_TRUE; 1062 } 1063 /* NOTE: we're adding the border here, not subtracting! */ 1064 if (yoffset + height > (GLint) (teximage->Height + teximage->Border)) { 1065 char message[100]; 1066 sprintf(message, "glCopyTexSubImage%dD(yoffset+height)", dimensions); 1067 _mesa_error(ctx, GL_INVALID_VALUE, message); 1068 return GL_TRUE; 1069 } 1070 } 1071 1072 if (dimensions > 2) { 1073 if (zoffset < -((GLint)teximage->Border)) { 1074 char message[100]; 1075 sprintf(message, "glCopyTexSubImage%dD(zoffset)", dimensions); 1076 _mesa_error(ctx, GL_INVALID_VALUE, message); 1077 return GL_TRUE; 1078 } 1079 if (zoffset > (GLint) (teximage->Depth + teximage->Border)) { 1080 char message[100]; 1081 sprintf(message, "glCopyTexSubImage%dD(zoffset+depth)", dimensions); 1082 _mesa_error(ctx, GL_INVALID_VALUE, message); 1083 return GL_TRUE; 1084 } 1085 } 1086 1087 /* if we get here, the parameters are OK */ 1088 return GL_FALSE; 1089} 1090 1091 1092 1093void 1094_mesa_GetTexImage( GLenum target, GLint level, GLenum format, 1095 GLenum type, GLvoid *pixels ) 1096{ 1097 const struct gl_texture_unit *texUnit; 1098 const struct gl_texture_object *texObj; 1099 struct gl_texture_image *texImage; 1100 GET_CURRENT_CONTEXT(ctx); 1101 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1102 1103 if (level < 0 || level >= ctx->Const.MaxTextureLevels) { 1104 _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" ); 1105 return; 1106 } 1107 1108 if (_mesa_sizeof_type(type) <= 0) { 1109 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" ); 1110 return; 1111 } 1112 1113 if (_mesa_components_in_format(format) <= 0 || 1114 format == GL_STENCIL_INDEX) { 1115 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" ); 1116 return; 1117 } 1118 1119 if (!ctx->Extensions.EXT_paletted_texture && is_index_format(format)) { 1120 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); 1121 } 1122 1123 if (!ctx->Extensions.SGIX_depth_texture && format == GL_DEPTH_COMPONENT) { 1124 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); 1125 } 1126 1127 /* XXX what if format/type doesn't match texture format/type? */ 1128 1129 if (!pixels) 1130 return; 1131 1132 texUnit = &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]); 1133 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1134 if (!texObj || is_proxy_target(target)) { 1135 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)"); 1136 return; 1137 } 1138 1139 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1140 if (!texImage) { 1141 /* invalid mipmap level, not an error */ 1142 return; 1143 } 1144 1145 if (!texImage->Data) { 1146 /* no image data, not an error */ 1147 return; 1148 } 1149 1150 if (ctx->NewState & _NEW_PIXEL) 1151 _mesa_update_state(ctx); 1152 1153 if (is_color_format(format) && 1154 ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 1155 /* convert texture image to GL_RGBA, GL_FLOAT */ 1156 GLint width = texImage->Width; 1157 GLint height = texImage->Height; 1158 GLint depth = texImage->Depth; 1159 GLint img, row; 1160 GLfloat *tmpImage, *convImage; 1161 tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat)); 1162 if (!tmpImage) { 1163 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); 1164 return; 1165 } 1166 convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat)); 1167 if (!convImage) { 1168 FREE(tmpImage); 1169 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); 1170 return; 1171 } 1172 1173 for (img = 0; img < depth; img++) { 1174 GLint convWidth, convHeight; 1175 1176 /* convert texture data to GLfloat/GL_RGBA */ 1177 for (row = 0; row < height; row++) { 1178 GLchan texels[1 << MAX_TEXTURE_LEVELS][4]; 1179 GLint col; 1180 GLfloat *dst = tmpImage + row * width * 4; 1181 for (col = 0; col < width; col++) { 1182 (*texImage->FetchTexel)(texImage, col, row, img, 1183 texels[col]); 1184 } 1185 _mesa_unpack_float_color_span(ctx, width, GL_RGBA, dst, 1186 GL_RGBA, CHAN_TYPE, texels, 1187 &_mesa_native_packing, 1188 ctx->_ImageTransferState & IMAGE_PRE_CONVOLUTION_BITS, 1189 GL_FALSE); 1190 } 1191 1192 convWidth = width; 1193 convHeight = height; 1194 1195 /* convolve */ 1196 if (target == GL_TEXTURE_1D) { 1197 if (ctx->Pixel.Convolution1DEnabled) { 1198 _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage); 1199 } 1200 } 1201 else { 1202 if (ctx->Pixel.Convolution2DEnabled) { 1203 _mesa_convolve_2d_image(ctx, &convWidth, &convHeight, 1204 tmpImage, convImage); 1205 } 1206 else if (ctx->Pixel.Separable2DEnabled) { 1207 _mesa_convolve_sep_image(ctx, &convWidth, &convHeight, 1208 tmpImage, convImage); 1209 } 1210 } 1211 1212 /* pack convolved image */ 1213 for (row = 0; row < convHeight; row++) { 1214 const GLfloat *src = convImage + row * convWidth * 4; 1215 GLvoid *dest = _mesa_image_address(&ctx->Pack, pixels, 1216 convWidth, convHeight, 1217 format, type, img, row, 0); 1218 _mesa_pack_float_rgba_span(ctx, convWidth, 1219 (const GLfloat(*)[4]) src, 1220 format, type, dest, &ctx->Pack, 1221 ctx->_ImageTransferState & IMAGE_POST_CONVOLUTION_BITS); 1222 } 1223 } 1224 1225 FREE(tmpImage); 1226 FREE(convImage); 1227 } 1228 else { 1229 /* no convolution, or non-rgba image */ 1230 GLint width = texImage->Width; 1231 GLint height = texImage->Height; 1232 GLint depth = texImage->Depth; 1233 GLint img, row; 1234 for (img = 0; img < depth; img++) { 1235 for (row = 0; row < height; row++) { 1236 /* compute destination address in client memory */ 1237 GLvoid *dest = _mesa_image_address( &ctx->Unpack, pixels, 1238 width, height, format, type, 1239 img, row, 0); 1240 assert(dest); 1241 1242 if (format == GL_COLOR_INDEX) { 1243 GLuint indexRow[MAX_WIDTH]; 1244 GLint col; 1245 for (col = 0; col < width; col++) { 1246 (*texImage->FetchTexel)(texImage, col, row, img, 1247 (GLvoid *) &indexRow[col]); 1248 } 1249 _mesa_pack_index_span(ctx, width, type, dest, 1250 indexRow, &ctx->Pack, 1251 ctx->_ImageTransferState); 1252 } 1253 else if (format == GL_DEPTH_COMPONENT) { 1254 GLfloat depthRow[MAX_WIDTH]; 1255 GLint col; 1256 for (col = 0; col < width; col++) { 1257 (*texImage->FetchTexel)(texImage, col, row, img, 1258 (GLvoid *) &depthRow[col]); 1259 } 1260 _mesa_pack_depth_span(ctx, width, dest, type, 1261 depthRow, &ctx->Pack); 1262 } 1263 else { 1264 /* general case: convert row to RGBA format */ 1265 GLchan rgba[MAX_WIDTH][4]; 1266 GLint col; 1267 for (col = 0; col < width; col++) { 1268 (*texImage->FetchTexel)(texImage, col, row, img, 1269 (GLvoid *) rgba[col]); 1270 } 1271 _mesa_pack_rgba_span(ctx, width, (const GLchan (*)[4])rgba, 1272 format, type, dest, &ctx->Pack, 1273 ctx->_ImageTransferState); 1274 } /* format */ 1275 } /* row */ 1276 } /* img */ 1277 } /* convolution */ 1278} 1279 1280 1281 1282/* 1283 * Called from the API. Note that width includes the border. 1284 */ 1285void 1286_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, 1287 GLsizei width, GLint border, GLenum format, 1288 GLenum type, const GLvoid *pixels ) 1289{ 1290 GLsizei postConvWidth = width; 1291 GET_CURRENT_CONTEXT(ctx); 1292 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1293 1294 if (is_color_format(internalFormat)) { 1295 _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); 1296 } 1297 1298 if (target == GL_TEXTURE_1D) { 1299 struct gl_texture_unit *texUnit; 1300 struct gl_texture_object *texObj; 1301 struct gl_texture_image *texImage; 1302 1303 if (texture_error_check(ctx, target, level, internalFormat, 1304 format, type, 1, postConvWidth, 1, 1, border)) { 1305 return; /* error was recorded */ 1306 } 1307 1308 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1309 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1310 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1311 1312 if (!texImage) { 1313 texImage = _mesa_alloc_texture_image(); 1314 texObj->Image[level] = texImage; 1315 if (!texImage) { 1316 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); 1317 return; 1318 } 1319 } 1320 else if (texImage->Data) { 1321 /* free the old texture data */ 1322 FREE(texImage->Data); 1323 texImage->Data = NULL; 1324 } 1325 clear_teximage_fields(texImage); /* not really needed, but helpful */ 1326 init_teximage_fields(ctx, texImage, postConvWidth, 1, 1, 1327 border, internalFormat); 1328 1329 if (ctx->NewState & _NEW_PIXEL) 1330 _mesa_update_state(ctx); 1331 1332 ASSERT(ctx->Driver.TexImage1D); 1333 if (pixels) { 1334 (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, 1335 width, border, format, type, pixels, 1336 &ctx->Unpack, texObj, texImage); 1337 } 1338 else { 1339 GLubyte *dummy = make_null_texture(width, 1, 1, format); 1340 if (dummy) { 1341 (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, 1342 width, border, 1343 format, GL_UNSIGNED_BYTE, dummy, 1344 &_mesa_native_packing, texObj, texImage); 1345 FREE(dummy); 1346 } 1347 } 1348 1349 ASSERT(texImage->TexFormat); 1350 texImage->FetchTexel = texImage->TexFormat->FetchTexel1D; 1351 1352 /* state update */ 1353 texObj->Complete = GL_FALSE; 1354 ctx->NewState |= _NEW_TEXTURE; 1355 } 1356 else if (target == GL_PROXY_TEXTURE_1D) { 1357 /* Proxy texture: check for errors and update proxy state */ 1358 GLenum error = texture_error_check(ctx, target, level, internalFormat, 1359 format, type, 1, 1360 postConvWidth, 1, 1, border); 1361 if (!error) { 1362 struct gl_texture_unit *texUnit; 1363 struct gl_texture_image *texImage; 1364 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1365 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1366 init_teximage_fields(ctx, texImage, postConvWidth, 1, 1, 1367 border, internalFormat); 1368 ASSERT(ctx->Driver.TestProxyTexImage); 1369 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 1370 internalFormat, format, type, 1371 postConvWidth, 1, 1, border); 1372 } 1373 if (error) { 1374 /* if error, clear all proxy texture image parameters */ 1375 if (level >= 0 && level < ctx->Const.MaxTextureLevels) { 1376 clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]); 1377 } 1378 } 1379 } 1380 else { 1381 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" ); 1382 return; 1383 } 1384} 1385 1386 1387void 1388_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, 1389 GLsizei width, GLsizei height, GLint border, 1390 GLenum format, GLenum type, 1391 const GLvoid *pixels ) 1392{ 1393 GLsizei postConvWidth = width, postConvHeight = height; 1394 GET_CURRENT_CONTEXT(ctx); 1395 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1396 1397 if (is_color_format(internalFormat)) { 1398 _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, 1399 &postConvHeight); 1400 } 1401 1402 if (target == GL_TEXTURE_2D || 1403 (ctx->Extensions.ARB_texture_cube_map && 1404 target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 1405 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { 1406 /* non-proxy target */ 1407 struct gl_texture_unit *texUnit; 1408 struct gl_texture_object *texObj; 1409 struct gl_texture_image *texImage; 1410 1411 if (texture_error_check(ctx, target, level, internalFormat, 1412 format, type, 2, postConvWidth, postConvHeight, 1413 1, border)) { 1414 return; /* error was recorded */ 1415 } 1416 1417 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1418 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1419 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1420 1421 if (!texImage) { 1422 texImage = _mesa_alloc_texture_image(); 1423 set_tex_image(texObj, target, level, texImage); 1424 if (!texImage) { 1425 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); 1426 return; 1427 } 1428 } 1429 else if (texImage->Data) { 1430 /* free the old texture data */ 1431 FREE(texImage->Data); 1432 texImage->Data = NULL; 1433 } 1434 clear_teximage_fields(texImage); /* not really needed, but helpful */ 1435 init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1, 1436 border, internalFormat); 1437 1438 if (ctx->NewState & _NEW_PIXEL) 1439 _mesa_update_state(ctx); 1440 1441 ASSERT(ctx->Driver.TexImage2D); 1442 if (pixels) { 1443 (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, 1444 width, height, border, format, type, pixels, 1445 &ctx->Unpack, texObj, texImage); 1446 } 1447 else { 1448 GLubyte *dummy = make_null_texture(width, height, 1, format); 1449 if (dummy) { 1450 (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, 1451 width, height, border, 1452 format, GL_UNSIGNED_BYTE, dummy, 1453 &_mesa_native_packing, texObj, texImage); 1454 FREE(dummy); 1455 } 1456 } 1457 1458 ASSERT(texImage->TexFormat); 1459 texImage->FetchTexel = texImage->TexFormat->FetchTexel2D; 1460 1461 /* state update */ 1462 texObj->Complete = GL_FALSE; 1463 ctx->NewState |= _NEW_TEXTURE; 1464 } 1465 else if (target == GL_PROXY_TEXTURE_2D) { 1466 /* Proxy texture: check for errors and update proxy state */ 1467 GLenum error = texture_error_check(ctx, target, level, internalFormat, 1468 format, type, 2, 1469 postConvWidth, postConvHeight, 1, border); 1470 if (!error) { 1471 struct gl_texture_unit *texUnit; 1472 struct gl_texture_image *texImage; 1473 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1474 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1475 init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1, 1476 border, internalFormat); 1477 ASSERT(ctx->Driver.TestProxyTexImage); 1478 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 1479 internalFormat, format, type, 1480 postConvWidth, postConvHeight, 1, border); 1481 } 1482 if (error) { 1483 /* if error, clear all proxy texture image parameters */ 1484 if (level >= 0 && level < ctx->Const.MaxTextureLevels) { 1485 clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]); 1486 } 1487 } 1488 } 1489 else { 1490 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" ); 1491 return; 1492 } 1493} 1494 1495 1496/* 1497 * Called by the API or display list executor. 1498 * Note that width and height include the border. 1499 */ 1500void 1501_mesa_TexImage3D( GLenum target, GLint level, GLenum internalFormat, 1502 GLsizei width, GLsizei height, GLsizei depth, 1503 GLint border, GLenum format, GLenum type, 1504 const GLvoid *pixels ) 1505{ 1506 GET_CURRENT_CONTEXT(ctx); 1507 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1508 1509 if (target == GL_TEXTURE_3D) { 1510 struct gl_texture_unit *texUnit; 1511 struct gl_texture_object *texObj; 1512 struct gl_texture_image *texImage; 1513 1514 if (texture_error_check(ctx, target, level, (GLint) internalFormat, 1515 format, type, 3, width, height, depth, border)) { 1516 return; /* error was recorded */ 1517 } 1518 1519 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1520 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1521 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1522 1523 if (!texImage) { 1524 texImage = _mesa_alloc_texture_image(); 1525 texObj->Image[level] = texImage; 1526 if (!texImage) { 1527 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); 1528 return; 1529 } 1530 } 1531 else if (texImage->Data) { 1532 FREE(texImage->Data); 1533 texImage->Data = NULL; 1534 } 1535 clear_teximage_fields(texImage); /* not really needed, but helpful */ 1536 init_teximage_fields(ctx, texImage, width, height, depth, border, 1537 internalFormat); 1538 1539 if (ctx->NewState & _NEW_PIXEL) 1540 _mesa_update_state(ctx); 1541 1542 ASSERT(ctx->Driver.TexImage3D); 1543 if (pixels) { 1544 (*ctx->Driver.TexImage3D)(ctx, target, level, (GLint) internalFormat, 1545 width, height, depth, border, 1546 format, type, pixels, 1547 &ctx->Unpack, texObj, texImage); 1548 } 1549 else { 1550 GLubyte *dummy = make_null_texture(width, height, depth, format); 1551 if (dummy) { 1552 (*ctx->Driver.TexImage3D)(ctx, target, level, 1553 (GLint) internalFormat, 1554 width, height, depth, border, 1555 format, GL_UNSIGNED_BYTE, dummy, 1556 &_mesa_native_packing, texObj, texImage); 1557 FREE(dummy); 1558 } 1559 } 1560 1561 ASSERT(texImage->TexFormat); 1562 texImage->FetchTexel = texImage->TexFormat->FetchTexel3D; 1563 1564 /* state update */ 1565 texObj->Complete = GL_FALSE; 1566 ctx->NewState |= _NEW_TEXTURE; 1567 } 1568 else if (target == GL_PROXY_TEXTURE_3D) { 1569 /* Proxy texture: check for errors and update proxy state */ 1570 GLenum error = texture_error_check(ctx, target, level, internalFormat, 1571 format, type, 3, width, height, depth, border); 1572 if (!error) { 1573 struct gl_texture_unit *texUnit; 1574 struct gl_texture_image *texImage; 1575 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1576 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1577 init_teximage_fields(ctx, texImage, width, height, 1, 1578 border, internalFormat); 1579 ASSERT(ctx->Driver.TestProxyTexImage); 1580 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 1581 internalFormat, format, type, 1582 width, height, depth, border); 1583 } 1584 if (error) { 1585 /* if error, clear all proxy texture image parameters */ 1586 if (level >= 0 && level < ctx->Const.MaxTextureLevels) { 1587 clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]); 1588 } 1589 } 1590 } 1591 else { 1592 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" ); 1593 return; 1594 } 1595} 1596 1597 1598void 1599_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat, 1600 GLsizei width, GLsizei height, GLsizei depth, 1601 GLint border, GLenum format, GLenum type, 1602 const GLvoid *pixels ) 1603{ 1604 _mesa_TexImage3D(target, level, internalFormat, width, height, 1605 depth, border, format, type, pixels); 1606} 1607 1608 1609 1610void 1611_mesa_TexSubImage1D( GLenum target, GLint level, 1612 GLint xoffset, GLsizei width, 1613 GLenum format, GLenum type, 1614 const GLvoid *pixels ) 1615{ 1616 GLsizei postConvWidth = width; 1617 struct gl_texture_unit *texUnit; 1618 struct gl_texture_object *texObj; 1619 struct gl_texture_image *texImage; 1620 GET_CURRENT_CONTEXT(ctx); 1621 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1622 1623 if (ctx->NewState & _NEW_PIXEL) 1624 _mesa_update_state(ctx); 1625 1626 /* XXX should test internal format */ 1627 if (is_color_format(format)) { 1628 _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); 1629 } 1630 1631 if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0, 1632 postConvWidth, 1, 1, format, type)) { 1633 return; /* error was detected */ 1634 } 1635 1636 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1637 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1638 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1639 assert(texImage); 1640 1641 if (width == 0 || !pixels) 1642 return; /* no-op, not an error */ 1643 1644 ASSERT(ctx->Driver.TexSubImage1D); 1645 (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, 1646 format, type, pixels, &ctx->Unpack, 1647 texObj, texImage); 1648 ctx->NewState |= _NEW_TEXTURE; 1649} 1650 1651 1652void 1653_mesa_TexSubImage2D( GLenum target, GLint level, 1654 GLint xoffset, GLint yoffset, 1655 GLsizei width, GLsizei height, 1656 GLenum format, GLenum type, 1657 const GLvoid *pixels ) 1658{ 1659 GLsizei postConvWidth = width, postConvHeight = height; 1660 struct gl_texture_unit *texUnit; 1661 struct gl_texture_object *texObj; 1662 struct gl_texture_image *texImage; 1663 GET_CURRENT_CONTEXT(ctx); 1664 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1665 1666 if (ctx->NewState & _NEW_PIXEL) 1667 _mesa_update_state(ctx); 1668 1669 /* XXX should test internal format */ 1670 if (is_color_format(format)) { 1671 _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, 1672 &postConvHeight); 1673 } 1674 1675 if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0, 1676 postConvWidth, postConvHeight, 1, format, type)) { 1677 return; /* error was detected */ 1678 } 1679 1680 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1681 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1682 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1683 assert(texImage); 1684 1685 if (width == 0 || height == 0 || !pixels) 1686 return; /* no-op, not an error */ 1687 1688 ASSERT(ctx->Driver.TexSubImage2D); 1689 (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset, 1690 width, height, format, type, pixels, 1691 &ctx->Unpack, texObj, texImage); 1692 ctx->NewState |= _NEW_TEXTURE; 1693} 1694 1695 1696 1697void 1698_mesa_TexSubImage3D( GLenum target, GLint level, 1699 GLint xoffset, GLint yoffset, GLint zoffset, 1700 GLsizei width, GLsizei height, GLsizei depth, 1701 GLenum format, GLenum type, 1702 const GLvoid *pixels ) 1703{ 1704 struct gl_texture_unit *texUnit; 1705 struct gl_texture_object *texObj; 1706 struct gl_texture_image *texImage; 1707 GET_CURRENT_CONTEXT(ctx); 1708 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1709 1710 if (ctx->NewState & _NEW_PIXEL) 1711 _mesa_update_state(ctx); 1712 1713 if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset, 1714 width, height, depth, format, type)) { 1715 return; /* error was detected */ 1716 } 1717 1718 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1719 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1720 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1721 assert(texImage); 1722 1723 if (width == 0 || height == 0 || height == 0 || !pixels) 1724 return; /* no-op, not an error */ 1725 1726 ASSERT(ctx->Driver.TexSubImage3D); 1727 (*ctx->Driver.TexSubImage3D)(ctx, target, level, 1728 xoffset, yoffset, zoffset, 1729 width, height, depth, 1730 format, type, pixels, 1731 &ctx->Unpack, texObj, texImage ); 1732 ctx->NewState |= _NEW_TEXTURE; 1733} 1734 1735 1736 1737void 1738_mesa_CopyTexImage1D( GLenum target, GLint level, 1739 GLenum internalFormat, 1740 GLint x, GLint y, 1741 GLsizei width, GLint border ) 1742{ 1743 struct gl_texture_unit *texUnit; 1744 struct gl_texture_object *texObj; 1745 struct gl_texture_image *texImage; 1746 GLsizei postConvWidth = width; 1747 GET_CURRENT_CONTEXT(ctx); 1748 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1749 1750 if (ctx->NewState & _NEW_PIXEL) 1751 _mesa_update_state(ctx); 1752 1753 if (is_color_format(internalFormat)) { 1754 _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); 1755 } 1756 1757 if (copytexture_error_check(ctx, 1, target, level, internalFormat, 1758 postConvWidth, 1, border)) 1759 return; 1760 1761 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1762 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1763 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1764 if (!texImage) { 1765 texImage = _mesa_alloc_texture_image(); 1766 set_tex_image(texObj, target, level, texImage); 1767 if (!texImage) { 1768 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); 1769 return; 1770 } 1771 } 1772 else if (texImage->Data) { 1773 /* free the old texture data */ 1774 FREE(texImage->Data); 1775 texImage->Data = NULL; 1776 } 1777 1778 clear_teximage_fields(texImage); /* not really needed, but helpful */ 1779 init_teximage_fields(ctx, texImage, postConvWidth, 1, 1, 1780 border, internalFormat); 1781 1782 1783 ASSERT(ctx->Driver.CopyTexImage1D); 1784 (*ctx->Driver.CopyTexImage1D)(ctx, target, level, internalFormat, 1785 x, y, width, border); 1786 1787 /* state update */ 1788 texObj->Complete = GL_FALSE; 1789 ctx->NewState |= _NEW_TEXTURE; 1790} 1791 1792 1793 1794void 1795_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, 1796 GLint x, GLint y, GLsizei width, GLsizei height, 1797 GLint border ) 1798{ 1799 struct gl_texture_unit *texUnit; 1800 struct gl_texture_object *texObj; 1801 struct gl_texture_image *texImage; 1802 GLsizei postConvWidth = width, postConvHeight = height; 1803 GET_CURRENT_CONTEXT(ctx); 1804 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1805 1806 if (ctx->NewState & _NEW_PIXEL) 1807 _mesa_update_state(ctx); 1808 1809 if (is_color_format(internalFormat)) { 1810 _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, 1811 &postConvHeight); 1812 } 1813 1814 if (copytexture_error_check(ctx, 2, target, level, internalFormat, 1815 postConvWidth, postConvHeight, border)) 1816 return; 1817 1818 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1819 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1820 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1821 if (!texImage) { 1822 texImage = _mesa_alloc_texture_image(); 1823 set_tex_image(texObj, target, level, texImage); 1824 if (!texImage) { 1825 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); 1826 return; 1827 } 1828 } 1829 else if (texImage->Data) { 1830 /* free the old texture data */ 1831 FREE(texImage->Data); 1832 texImage->Data = NULL; 1833 } 1834 1835 clear_teximage_fields(texImage); /* not really needed, but helpful */ 1836 init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1, 1837 border, internalFormat); 1838 1839 ASSERT(ctx->Driver.CopyTexImage2D); 1840 (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat, 1841 x, y, width, height, border); 1842 1843 /* state update */ 1844 texObj->Complete = GL_FALSE; 1845 ctx->NewState |= _NEW_TEXTURE; 1846} 1847 1848 1849 1850void 1851_mesa_CopyTexSubImage1D( GLenum target, GLint level, 1852 GLint xoffset, GLint x, GLint y, GLsizei width ) 1853{ 1854 GLsizei postConvWidth = width; 1855 GET_CURRENT_CONTEXT(ctx); 1856 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1857 1858 if (ctx->NewState & _NEW_PIXEL) 1859 _mesa_update_state(ctx); 1860 1861 /* XXX should test internal format */ 1862 _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); 1863 1864 if (copytexsubimage_error_check(ctx, 1, target, level, 1865 xoffset, 0, 0, postConvWidth, 1)) 1866 return; 1867 1868 ASSERT(ctx->Driver.CopyTexSubImage1D); 1869 (*ctx->Driver.CopyTexSubImage1D)(ctx, target, level, xoffset, x, y, width); 1870 ctx->NewState |= _NEW_TEXTURE; 1871} 1872 1873 1874 1875void 1876_mesa_CopyTexSubImage2D( GLenum target, GLint level, 1877 GLint xoffset, GLint yoffset, 1878 GLint x, GLint y, GLsizei width, GLsizei height ) 1879{ 1880 GLsizei postConvWidth = width, postConvHeight = height; 1881 GET_CURRENT_CONTEXT(ctx); 1882 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1883 1884 if (ctx->NewState & _NEW_PIXEL) 1885 _mesa_update_state(ctx); 1886 1887 /* XXX should test internal format */ 1888 _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); 1889 1890 if (copytexsubimage_error_check(ctx, 2, target, level, xoffset, yoffset, 0, 1891 postConvWidth, postConvHeight)) 1892 return; 1893 1894 ASSERT(ctx->Driver.CopyTexSubImage2D); 1895 (*ctx->Driver.CopyTexSubImage2D)(ctx, target, level, 1896 xoffset, yoffset, x, y, width, height); 1897 ctx->NewState |= _NEW_TEXTURE; 1898} 1899 1900 1901 1902void 1903_mesa_CopyTexSubImage3D( GLenum target, GLint level, 1904 GLint xoffset, GLint yoffset, GLint zoffset, 1905 GLint x, GLint y, GLsizei width, GLsizei height ) 1906{ 1907 GLsizei postConvWidth = width, postConvHeight = height; 1908 GET_CURRENT_CONTEXT(ctx); 1909 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1910 1911 if (ctx->NewState & _NEW_PIXEL) 1912 _mesa_update_state(ctx); 1913 1914 /* XXX should test internal format */ 1915 _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); 1916 1917 if (copytexsubimage_error_check(ctx, 3, target, level, xoffset, yoffset, 1918 zoffset, postConvWidth, postConvHeight)) 1919 return; 1920 1921 ASSERT(ctx->Driver.CopyTexSubImage3D); 1922 (*ctx->Driver.CopyTexSubImage3D)(ctx, target, level, 1923 xoffset, yoffset, zoffset, 1924 x, y, width, height); 1925 ctx->NewState |= _NEW_TEXTURE; 1926} 1927 1928 1929 1930void 1931_mesa_CompressedTexImage1DARB(GLenum target, GLint level, 1932 GLenum internalFormat, GLsizei width, 1933 GLint border, GLsizei imageSize, 1934 const GLvoid *data) 1935{ 1936 GET_CURRENT_CONTEXT(ctx); 1937 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1938 1939 switch (internalFormat) { 1940 case GL_COMPRESSED_ALPHA_ARB: 1941 case GL_COMPRESSED_LUMINANCE_ARB: 1942 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: 1943 case GL_COMPRESSED_INTENSITY_ARB: 1944 case GL_COMPRESSED_RGB_ARB: 1945 case GL_COMPRESSED_RGBA_ARB: 1946 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1DARB"); 1947 return; 1948 default: 1949 /* silence compiler warning */ 1950 ; 1951 } 1952 1953 if (target == GL_TEXTURE_1D) { 1954 struct gl_texture_unit *texUnit; 1955 struct gl_texture_object *texObj; 1956 struct gl_texture_image *texImage; 1957 1958 if (texture_error_check(ctx, target, level, internalFormat, 1959 GL_NONE, GL_NONE, 1, width, 1, 1, border)) { 1960 return; /* error in texture image was detected */ 1961 } 1962 1963 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1964 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1965 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1966 1967 if (!texImage) { 1968 texImage = _mesa_alloc_texture_image(); 1969 texObj->Image[level] = texImage; 1970 if (!texImage) { 1971 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1DARB"); 1972 return; 1973 } 1974 } 1975 else if (texImage->Data) { 1976 FREE(texImage->Data); 1977 texImage->Data = NULL; 1978 } 1979 1980 init_teximage_fields(ctx, texImage, width, 1, 1, border, internalFormat); 1981 1982 if (ctx->Extensions.ARB_texture_compression) { 1983 ASSERT(ctx->Driver.CompressedTexImage1D); 1984 (*ctx->Driver.CompressedTexImage1D)(ctx, target, level, 1985 internalFormat, width, border, 1986 imageSize, data, 1987 texObj, texImage); 1988 ASSERT(texImage->CompressedSize > 0); /* sanity */ 1989 } 1990 1991 /* state update */ 1992 texObj->Complete = GL_FALSE; 1993 ctx->NewState |= _NEW_TEXTURE; 1994 } 1995 else if (target == GL_PROXY_TEXTURE_1D) { 1996 /* Proxy texture: check for errors and update proxy state */ 1997 GLenum error = texture_error_check(ctx, target, level, internalFormat, 1998 GL_NONE, GL_NONE, 1, width, 1, 1, border); 1999 if (!error) { 2000 struct gl_texture_unit *texUnit; 2001 struct gl_texture_image *texImage; 2002 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2003 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2004 init_teximage_fields(ctx, texImage, width, 1, 1, 2005 border, internalFormat); 2006 ASSERT(ctx->Driver.TestProxyTexImage); 2007 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 2008 internalFormat, GL_NONE, GL_NONE, 2009 width, 1, 1, border); 2010 } 2011 if (error) { 2012 /* if error, clear all proxy texture image parameters */ 2013 if (level >= 0 && level < ctx->Const.MaxTextureLevels) { 2014 clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]); 2015 } 2016 } 2017 } 2018 else { 2019 _mesa_error( ctx, GL_INVALID_ENUM, "glCompressedTexImage1DARB(target)" ); 2020 return; 2021 } 2022} 2023 2024 2025void 2026_mesa_CompressedTexImage2DARB(GLenum target, GLint level, 2027 GLenum internalFormat, GLsizei width, 2028 GLsizei height, GLint border, GLsizei imageSize, 2029 const GLvoid *data) 2030{ 2031 GET_CURRENT_CONTEXT(ctx); 2032 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2033 2034 switch (internalFormat) { 2035 case GL_COMPRESSED_ALPHA_ARB: 2036 case GL_COMPRESSED_LUMINANCE_ARB: 2037 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: 2038 case GL_COMPRESSED_INTENSITY_ARB: 2039 case GL_COMPRESSED_RGB_ARB: 2040 case GL_COMPRESSED_RGBA_ARB: 2041 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2DARB"); 2042 return; 2043 default: 2044 /* silence compiler warning */ 2045 ; 2046 } 2047 2048 if (target == GL_TEXTURE_2D || 2049 (ctx->Extensions.ARB_texture_cube_map && 2050 target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 2051 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { 2052 struct gl_texture_unit *texUnit; 2053 struct gl_texture_object *texObj; 2054 struct gl_texture_image *texImage; 2055 2056 if (texture_error_check(ctx, target, level, internalFormat, 2057 GL_NONE, GL_NONE, 1, width, height, 1, border)) { 2058 return; /* error in texture image was detected */ 2059 } 2060 2061 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2062 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2063 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2064 2065 if (!texImage) { 2066 texImage = _mesa_alloc_texture_image(); 2067 texObj->Image[level] = texImage; 2068 if (!texImage) { 2069 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB"); 2070 return; 2071 } 2072 } 2073 else if (texImage->Data) { 2074 FREE(texImage->Data); 2075 texImage->Data = NULL; 2076 } 2077 2078 init_teximage_fields(ctx, texImage, width, height, 1, border, 2079 internalFormat); 2080 2081 if (ctx->Extensions.ARB_texture_compression) { 2082 ASSERT(ctx->Driver.CompressedTexImage2D); 2083 (*ctx->Driver.CompressedTexImage2D)(ctx, target, level, 2084 internalFormat, width, height, 2085 border, imageSize, data, 2086 texObj, texImage); 2087 ASSERT(texImage->CompressedSize > 0); /* sanity */ 2088 } 2089 2090 /* state update */ 2091 texObj->Complete = GL_FALSE; 2092 ctx->NewState |= _NEW_TEXTURE; 2093 } 2094 else if (target == GL_PROXY_TEXTURE_2D) { 2095 /* Proxy texture: check for errors and update proxy state */ 2096 GLenum error = texture_error_check(ctx, target, level, internalFormat, 2097 GL_NONE, GL_NONE, 2, width, height, 1, border); 2098 if (!error) { 2099 struct gl_texture_unit *texUnit; 2100 struct gl_texture_image *texImage; 2101 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2102 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2103 init_teximage_fields(ctx, texImage, width, height, 1, 2104 border, internalFormat); 2105 ASSERT(ctx->Driver.TestProxyTexImage); 2106 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 2107 internalFormat, GL_NONE, GL_NONE, 2108 width, height, 1, border); 2109 } 2110 if (error) { 2111 /* if error, clear all proxy texture image parameters */ 2112 if (level >= 0 && level < ctx->Const.MaxTextureLevels) { 2113 clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]); 2114 } 2115 } 2116 } 2117 else { 2118 _mesa_error( ctx, GL_INVALID_ENUM, "glCompressedTexImage2DARB(target)" ); 2119 return; 2120 } 2121} 2122 2123 2124void 2125_mesa_CompressedTexImage3DARB(GLenum target, GLint level, 2126 GLenum internalFormat, GLsizei width, 2127 GLsizei height, GLsizei depth, GLint border, 2128 GLsizei imageSize, const GLvoid *data) 2129{ 2130 GET_CURRENT_CONTEXT(ctx); 2131 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2132 2133 switch (internalFormat) { 2134 case GL_COMPRESSED_ALPHA_ARB: 2135 case GL_COMPRESSED_LUMINANCE_ARB: 2136 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: 2137 case GL_COMPRESSED_INTENSITY_ARB: 2138 case GL_COMPRESSED_RGB_ARB: 2139 case GL_COMPRESSED_RGBA_ARB: 2140 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3DARB"); 2141 return; 2142 default: 2143 /* silence compiler warning */ 2144 ; 2145 } 2146 2147 if (target == GL_TEXTURE_3D) { 2148 struct gl_texture_unit *texUnit; 2149 struct gl_texture_object *texObj; 2150 struct gl_texture_image *texImage; 2151 2152 if (texture_error_check(ctx, target, level, internalFormat, 2153 GL_NONE, GL_NONE, 1, width, height, depth, border)) { 2154 return; /* error in texture image was detected */ 2155 } 2156 2157 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2158 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2159 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2160 2161 if (!texImage) { 2162 texImage = _mesa_alloc_texture_image(); 2163 texObj->Image[level] = texImage; 2164 if (!texImage) { 2165 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3DARB"); 2166 return; 2167 } 2168 } 2169 else if (texImage->Data) { 2170 FREE(texImage->Data); 2171 texImage->Data = NULL; 2172 } 2173 2174 init_teximage_fields(ctx, texImage, width, height, depth, border, 2175 internalFormat); 2176 2177 if (ctx->Extensions.ARB_texture_compression) { 2178 ASSERT(ctx->Driver.CompressedTexImage3D); 2179 (*ctx->Driver.CompressedTexImage3D)(ctx, target, level, 2180 internalFormat, 2181 width, height, depth, 2182 border, imageSize, data, 2183 texObj, texImage); 2184 ASSERT(texImage->CompressedSize > 0); /* sanity */ 2185 } 2186 2187 /* state update */ 2188 texObj->Complete = GL_FALSE; 2189 ctx->NewState |= _NEW_TEXTURE; 2190 } 2191 else if (target == GL_PROXY_TEXTURE_3D) { 2192 /* Proxy texture: check for errors and update proxy state */ 2193 GLenum error = texture_error_check(ctx, target, level, internalFormat, 2194 GL_NONE, GL_NONE, 1, width, height, depth, border); 2195 if (!error) { 2196 struct gl_texture_unit *texUnit; 2197 struct gl_texture_image *texImage; 2198 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2199 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2200 init_teximage_fields(ctx, texImage, width, height, depth, 2201 border, internalFormat); 2202 ASSERT(ctx->Driver.TestProxyTexImage); 2203 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 2204 internalFormat, GL_NONE, GL_NONE, 2205 width, height, depth, border); 2206 } 2207 if (error) { 2208 /* if error, clear all proxy texture image parameters */ 2209 if (level >= 0 && level < ctx->Const.MaxTextureLevels) { 2210 clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]); 2211 } 2212 } 2213 } 2214 else { 2215 _mesa_error( ctx, GL_INVALID_ENUM, "glCompressedTexImage3DARB(target)" ); 2216 return; 2217 } 2218} 2219 2220 2221void 2222_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, 2223 GLsizei width, GLenum format, 2224 GLsizei imageSize, const GLvoid *data) 2225{ 2226 struct gl_texture_unit *texUnit; 2227 struct gl_texture_object *texObj; 2228 struct gl_texture_image *texImage; 2229 GET_CURRENT_CONTEXT(ctx); 2230 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2231 2232 if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0, 2233 width, 1, 1, format, GL_NONE)) { 2234 return; /* error was detected */ 2235 } 2236 2237 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2238 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2239 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2240 assert(texImage); 2241 2242 if (width == 0 || !data) 2243 return; /* no-op, not an error */ 2244 2245 if (ctx->Driver.CompressedTexSubImage1D) { 2246 (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level, 2247 xoffset, width, 2248 format, imageSize, data, 2249 texObj, texImage); 2250 } 2251 ctx->NewState |= _NEW_TEXTURE; 2252} 2253 2254 2255void 2256_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, 2257 GLint yoffset, GLsizei width, GLsizei height, 2258 GLenum format, GLsizei imageSize, 2259 const GLvoid *data) 2260{ 2261 struct gl_texture_unit *texUnit; 2262 struct gl_texture_object *texObj; 2263 struct gl_texture_image *texImage; 2264 GET_CURRENT_CONTEXT(ctx); 2265 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2266 2267 if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0, 2268 width, height, 1, format, GL_NONE)) { 2269 return; /* error was detected */ 2270 } 2271 2272 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2273 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2274 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2275 assert(texImage); 2276 2277 if (width == 0 || height == 0 || !data) 2278 return; /* no-op, not an error */ 2279 2280 if (ctx->Driver.CompressedTexSubImage2D) { 2281 (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level, 2282 xoffset, yoffset, width, height, 2283 format, imageSize, data, 2284 texObj, texImage); 2285 } 2286 ctx->NewState |= _NEW_TEXTURE; 2287} 2288 2289 2290void 2291_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, 2292 GLint yoffset, GLint zoffset, GLsizei width, 2293 GLsizei height, GLsizei depth, GLenum format, 2294 GLsizei imageSize, const GLvoid *data) 2295{ 2296 struct gl_texture_unit *texUnit; 2297 struct gl_texture_object *texObj; 2298 struct gl_texture_image *texImage; 2299 GET_CURRENT_CONTEXT(ctx); 2300 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2301 2302 if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset, 2303 width, height, depth, format, GL_NONE)) { 2304 return; /* error was detected */ 2305 } 2306 2307 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2308 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2309 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2310 assert(texImage); 2311 2312 if (width == 0 || height == 0 || depth == 0 || !data) 2313 return; /* no-op, not an error */ 2314 2315 if (ctx->Driver.CompressedTexSubImage3D) { 2316 (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level, 2317 xoffset, yoffset, zoffset, 2318 width, height, depth, 2319 format, imageSize, data, 2320 texObj, texImage); 2321 } 2322 ctx->NewState |= _NEW_TEXTURE; 2323} 2324 2325 2326void 2327_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img) 2328{ 2329 const struct gl_texture_unit *texUnit; 2330 const struct gl_texture_object *texObj; 2331 struct gl_texture_image *texImage; 2332 GET_CURRENT_CONTEXT(ctx); 2333 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2334 2335 if (level < 0 || level >= ctx->Const.MaxTextureLevels) { 2336 _mesa_error( ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)" ); 2337 return; 2338 } 2339 2340 if (is_proxy_target(target)) { 2341 _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)"); 2342 return; 2343 } 2344 2345 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2346 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2347 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2348 2349 if (!texImage) { 2350 /* invalid mipmap level */ 2351 _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)"); 2352 return; 2353 } 2354 2355 if (!texImage->IsCompressed) { 2356 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetCompressedTexImageARB"); 2357 return; 2358 } 2359 2360 if (!img) 2361 return; 2362 2363 if (ctx->Extensions.ARB_texture_compression) { 2364 ASSERT(ctx->Driver.GetCompressedTexImage); 2365 (*ctx->Driver.GetCompressedTexImage)(ctx, target, level, img, texObj, 2366 texImage); 2367 } 2368} 2369