texstate.c revision 7117f1b4
1/* 2 * Mesa 3-D graphics library 3 * Version: 6.5.3 4 * 5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25/** 26 * \file texstate.c 27 * 28 * Texture state handling. 29 */ 30 31#include "glheader.h" 32#include "colormac.h" 33#include "colortab.h" 34#include "context.h" 35#include "enums.h" 36#include "macros.h" 37#include "texcompress.h" 38#include "texobj.h" 39#include "teximage.h" 40#include "texstate.h" 41#include "texenvprogram.h" 42#include "mtypes.h" 43#include "math/m_xform.h" 44 45 46#define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X)) 47#define ENUM_TO_DOUBLE(X) ((GLdouble)(GLint)(X)) 48 49 50/** 51 * Default texture combine environment state. This is used to initialize 52 * a context's texture units and as the basis for converting "classic" 53 * texture environmnets to ARB_texture_env_combine style values. 54 */ 55static const struct gl_tex_env_combine_state default_combine_state = { 56 GL_MODULATE, GL_MODULATE, 57 { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT }, 58 { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT }, 59 { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA }, 60 { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA }, 61 0, 0, 62 2, 2 63}; 64 65 66 67/** 68 * Used by glXCopyContext to copy texture state from one context to another. 69 */ 70void 71_mesa_copy_texture_state( const GLcontext *src, GLcontext *dst ) 72{ 73 GLuint i; 74 75 ASSERT(src); 76 ASSERT(dst); 77 78 dst->Texture.CurrentUnit = src->Texture.CurrentUnit; 79 dst->Texture._GenFlags = src->Texture._GenFlags; 80 dst->Texture._TexGenEnabled = src->Texture._TexGenEnabled; 81 dst->Texture._TexMatEnabled = src->Texture._TexMatEnabled; 82 dst->Texture.SharedPalette = src->Texture.SharedPalette; 83 84 /* per-unit state */ 85 for (i = 0; i < src->Const.MaxTextureUnits; i++) { 86 dst->Texture.Unit[i].Enabled = src->Texture.Unit[i].Enabled; 87 dst->Texture.Unit[i].EnvMode = src->Texture.Unit[i].EnvMode; 88 COPY_4V(dst->Texture.Unit[i].EnvColor, src->Texture.Unit[i].EnvColor); 89 dst->Texture.Unit[i].TexGenEnabled = src->Texture.Unit[i].TexGenEnabled; 90 dst->Texture.Unit[i].GenModeS = src->Texture.Unit[i].GenModeS; 91 dst->Texture.Unit[i].GenModeT = src->Texture.Unit[i].GenModeT; 92 dst->Texture.Unit[i].GenModeR = src->Texture.Unit[i].GenModeR; 93 dst->Texture.Unit[i].GenModeQ = src->Texture.Unit[i].GenModeQ; 94 dst->Texture.Unit[i]._GenBitS = src->Texture.Unit[i]._GenBitS; 95 dst->Texture.Unit[i]._GenBitT = src->Texture.Unit[i]._GenBitT; 96 dst->Texture.Unit[i]._GenBitR = src->Texture.Unit[i]._GenBitR; 97 dst->Texture.Unit[i]._GenBitQ = src->Texture.Unit[i]._GenBitQ; 98 dst->Texture.Unit[i]._GenFlags = src->Texture.Unit[i]._GenFlags; 99 COPY_4V(dst->Texture.Unit[i].ObjectPlaneS, src->Texture.Unit[i].ObjectPlaneS); 100 COPY_4V(dst->Texture.Unit[i].ObjectPlaneT, src->Texture.Unit[i].ObjectPlaneT); 101 COPY_4V(dst->Texture.Unit[i].ObjectPlaneR, src->Texture.Unit[i].ObjectPlaneR); 102 COPY_4V(dst->Texture.Unit[i].ObjectPlaneQ, src->Texture.Unit[i].ObjectPlaneQ); 103 COPY_4V(dst->Texture.Unit[i].EyePlaneS, src->Texture.Unit[i].EyePlaneS); 104 COPY_4V(dst->Texture.Unit[i].EyePlaneT, src->Texture.Unit[i].EyePlaneT); 105 COPY_4V(dst->Texture.Unit[i].EyePlaneR, src->Texture.Unit[i].EyePlaneR); 106 COPY_4V(dst->Texture.Unit[i].EyePlaneQ, src->Texture.Unit[i].EyePlaneQ); 107 dst->Texture.Unit[i].LodBias = src->Texture.Unit[i].LodBias; 108 109 /* GL_EXT_texture_env_combine */ 110 dst->Texture.Unit[i].Combine.ModeRGB = src->Texture.Unit[i].Combine.ModeRGB; 111 dst->Texture.Unit[i].Combine.ModeA = src->Texture.Unit[i].Combine.ModeA; 112 COPY_3V(dst->Texture.Unit[i].Combine.SourceRGB, src->Texture.Unit[i].Combine.SourceRGB); 113 COPY_3V(dst->Texture.Unit[i].Combine.SourceA, src->Texture.Unit[i].Combine.SourceA); 114 COPY_3V(dst->Texture.Unit[i].Combine.OperandRGB, src->Texture.Unit[i].Combine.OperandRGB); 115 COPY_3V(dst->Texture.Unit[i].Combine.OperandA, src->Texture.Unit[i].Combine.OperandA); 116 dst->Texture.Unit[i].Combine.ScaleShiftRGB = src->Texture.Unit[i].Combine.ScaleShiftRGB; 117 dst->Texture.Unit[i].Combine.ScaleShiftA = src->Texture.Unit[i].Combine.ScaleShiftA; 118 119 /* copy texture object bindings, not contents of texture objects */ 120 _mesa_lock_context_textures(dst); 121 122 _mesa_reference_texobj(&dst->Texture.Unit[i].Current1D, 123 src->Texture.Unit[i].Current1D); 124 _mesa_reference_texobj(&dst->Texture.Unit[i].Current2D, 125 src->Texture.Unit[i].Current2D); 126 _mesa_reference_texobj(&dst->Texture.Unit[i].Current3D, 127 src->Texture.Unit[i].Current3D); 128 _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentCubeMap, 129 src->Texture.Unit[i].CurrentCubeMap); 130 _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentRect, 131 src->Texture.Unit[i].CurrentRect); 132 133 _mesa_unlock_context_textures(dst); 134 } 135} 136 137 138/* 139 * For debugging 140 */ 141void 142_mesa_print_texunit_state( GLcontext *ctx, GLuint unit ) 143{ 144 const struct gl_texture_unit *texUnit = ctx->Texture.Unit + unit; 145 _mesa_printf("Texture Unit %d\n", unit); 146 _mesa_printf(" GL_TEXTURE_ENV_MODE = %s\n", _mesa_lookup_enum_by_nr(texUnit->EnvMode)); 147 _mesa_printf(" GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB)); 148 _mesa_printf(" GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA)); 149 _mesa_printf(" GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[0])); 150 _mesa_printf(" GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[1])); 151 _mesa_printf(" GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[2])); 152 _mesa_printf(" GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[0])); 153 _mesa_printf(" GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[1])); 154 _mesa_printf(" GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[2])); 155 _mesa_printf(" GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[0])); 156 _mesa_printf(" GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[1])); 157 _mesa_printf(" GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[2])); 158 _mesa_printf(" GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[0])); 159 _mesa_printf(" GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[1])); 160 _mesa_printf(" GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[2])); 161 _mesa_printf(" GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB); 162 _mesa_printf(" GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA); 163 _mesa_printf(" GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]); 164} 165 166 167 168/**********************************************************************/ 169/* Texture Environment */ 170/**********************************************************************/ 171 172/** 173 * Convert "classic" texture environment to ARB_texture_env_combine style 174 * environments. 175 * 176 * \param state texture_env_combine state vector to be filled-in. 177 * \param mode Classic texture environment mode (i.e., \c GL_REPLACE, 178 * \c GL_BLEND, \c GL_DECAL, etc.). 179 * \param texBaseFormat Base format of the texture associated with the 180 * texture unit. 181 */ 182static void 183calculate_derived_texenv( struct gl_tex_env_combine_state *state, 184 GLenum mode, GLenum texBaseFormat ) 185{ 186 GLenum mode_rgb; 187 GLenum mode_a; 188 189 *state = default_combine_state; 190 191 switch (texBaseFormat) { 192 case GL_ALPHA: 193 state->SourceRGB[0] = GL_PREVIOUS; 194 break; 195 196 case GL_LUMINANCE_ALPHA: 197 case GL_INTENSITY: 198 case GL_RGBA: 199 break; 200 201 case GL_LUMINANCE: 202 case GL_RGB: 203 case GL_YCBCR_MESA: 204 state->SourceA[0] = GL_PREVIOUS; 205 break; 206 207 default: 208 _mesa_problem(NULL, "Invalid texBaseFormat in calculate_derived_texenv"); 209 return; 210 } 211 212 switch (mode) { 213 case GL_REPLACE: 214 case GL_MODULATE: 215 mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode; 216 mode_a = mode; 217 break; 218 219 case GL_DECAL: 220 mode_rgb = GL_INTERPOLATE; 221 mode_a = GL_REPLACE; 222 223 state->SourceA[0] = GL_PREVIOUS; 224 225 /* Having alpha / luminance / intensity textures replace using the 226 * incoming fragment color matches the definition in NV_texture_shader. 227 * The 1.5 spec simply marks these as "undefined". 228 */ 229 switch (texBaseFormat) { 230 case GL_ALPHA: 231 case GL_LUMINANCE: 232 case GL_LUMINANCE_ALPHA: 233 case GL_INTENSITY: 234 state->SourceRGB[0] = GL_PREVIOUS; 235 break; 236 case GL_RGB: 237 case GL_YCBCR_MESA: 238 mode_rgb = GL_REPLACE; 239 break; 240 case GL_RGBA: 241 state->SourceRGB[2] = GL_TEXTURE; 242 break; 243 } 244 break; 245 246 case GL_BLEND: 247 mode_rgb = GL_INTERPOLATE; 248 mode_a = GL_MODULATE; 249 250 switch (texBaseFormat) { 251 case GL_ALPHA: 252 mode_rgb = GL_REPLACE; 253 break; 254 case GL_INTENSITY: 255 mode_a = GL_INTERPOLATE; 256 state->SourceA[0] = GL_CONSTANT; 257 state->OperandA[2] = GL_SRC_ALPHA; 258 /* FALLTHROUGH */ 259 case GL_LUMINANCE: 260 case GL_RGB: 261 case GL_LUMINANCE_ALPHA: 262 case GL_RGBA: 263 case GL_YCBCR_MESA: 264 state->SourceRGB[2] = GL_TEXTURE; 265 state->SourceA[2] = GL_TEXTURE; 266 state->SourceRGB[0] = GL_CONSTANT; 267 state->OperandRGB[2] = GL_SRC_COLOR; 268 break; 269 } 270 break; 271 272 case GL_ADD: 273 mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : GL_ADD; 274 mode_a = (texBaseFormat == GL_INTENSITY) ? GL_ADD : GL_MODULATE; 275 break; 276 277 default: 278 _mesa_problem(NULL, 279 "Invalid texture env mode in calculate_derived_texenv"); 280 return; 281 } 282 283 state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS) 284 ? mode_rgb : GL_REPLACE; 285 state->ModeA = (state->SourceA[0] != GL_PREVIOUS) 286 ? mode_a : GL_REPLACE; 287} 288 289 290void GLAPIENTRY 291_mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) 292{ 293 GLuint maxUnit; 294 GET_CURRENT_CONTEXT(ctx); 295 struct gl_texture_unit *texUnit; 296 ASSERT_OUTSIDE_BEGIN_END(ctx); 297 298 maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV) 299 ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits; 300 if (ctx->Texture.CurrentUnit >= maxUnit) { 301 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexEnvfv(current unit)"); 302 return; 303 } 304 305 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 306 307#define TE_ERROR(errCode, msg, value) \ 308 _mesa_error(ctx, errCode, msg, _mesa_lookup_enum_by_nr(value)); 309 310 if (target == GL_TEXTURE_ENV) { 311 switch (pname) { 312 case GL_TEXTURE_ENV_MODE: 313 { 314 const GLenum mode = (GLenum) (GLint) *param; 315 if (texUnit->EnvMode == mode) 316 return; 317 if (mode == GL_MODULATE || 318 mode == GL_BLEND || 319 mode == GL_DECAL || 320 mode == GL_REPLACE || 321 (mode == GL_ADD && ctx->Extensions.EXT_texture_env_add) || 322 (mode == GL_COMBINE && 323 (ctx->Extensions.EXT_texture_env_combine || 324 ctx->Extensions.ARB_texture_env_combine))) { 325 /* legal */ 326 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 327 texUnit->EnvMode = mode; 328 } 329 else { 330 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); 331 return; 332 } 333 } 334 break; 335 case GL_TEXTURE_ENV_COLOR: 336 { 337 GLfloat tmp[4]; 338 tmp[0] = CLAMP( param[0], 0.0F, 1.0F ); 339 tmp[1] = CLAMP( param[1], 0.0F, 1.0F ); 340 tmp[2] = CLAMP( param[2], 0.0F, 1.0F ); 341 tmp[3] = CLAMP( param[3], 0.0F, 1.0F ); 342 if (TEST_EQ_4V(tmp, texUnit->EnvColor)) 343 return; 344 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 345 COPY_4FV(texUnit->EnvColor, tmp); 346 } 347 break; 348 case GL_COMBINE_RGB: 349 if (ctx->Extensions.EXT_texture_env_combine || 350 ctx->Extensions.ARB_texture_env_combine) { 351 const GLenum mode = (GLenum) (GLint) *param; 352 if (texUnit->Combine.ModeRGB == mode) 353 return; 354 switch (mode) { 355 case GL_REPLACE: 356 case GL_MODULATE: 357 case GL_ADD: 358 case GL_ADD_SIGNED: 359 case GL_INTERPOLATE: 360 /* OK */ 361 break; 362 case GL_SUBTRACT: 363 if (!ctx->Extensions.ARB_texture_env_combine) { 364 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); 365 return; 366 } 367 break; 368 case GL_DOT3_RGB_EXT: 369 case GL_DOT3_RGBA_EXT: 370 if (!ctx->Extensions.EXT_texture_env_dot3) { 371 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); 372 return; 373 } 374 break; 375 case GL_DOT3_RGB: 376 case GL_DOT3_RGBA: 377 if (!ctx->Extensions.ARB_texture_env_dot3) { 378 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); 379 return; 380 } 381 break; 382 case GL_MODULATE_ADD_ATI: 383 case GL_MODULATE_SIGNED_ADD_ATI: 384 case GL_MODULATE_SUBTRACT_ATI: 385 if (!ctx->Extensions.ATI_texture_env_combine3) { 386 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); 387 return; 388 } 389 break; 390 default: 391 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); 392 return; 393 } 394 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 395 texUnit->Combine.ModeRGB = mode; 396 } 397 else { 398 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 399 return; 400 } 401 break; 402 case GL_COMBINE_ALPHA: 403 if (ctx->Extensions.EXT_texture_env_combine || 404 ctx->Extensions.ARB_texture_env_combine) { 405 const GLenum mode = (GLenum) (GLint) *param; 406 if (texUnit->Combine.ModeA == mode) 407 return; 408 switch (mode) { 409 case GL_REPLACE: 410 case GL_MODULATE: 411 case GL_ADD: 412 case GL_ADD_SIGNED: 413 case GL_INTERPOLATE: 414 /* OK */ 415 break; 416 case GL_SUBTRACT: 417 if (!ctx->Extensions.ARB_texture_env_combine) { 418 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); 419 return; 420 } 421 break; 422 case GL_MODULATE_ADD_ATI: 423 case GL_MODULATE_SIGNED_ADD_ATI: 424 case GL_MODULATE_SUBTRACT_ATI: 425 if (!ctx->Extensions.ATI_texture_env_combine3) { 426 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); 427 return; 428 } 429 break; 430 default: 431 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); 432 return; 433 } 434 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 435 texUnit->Combine.ModeA = mode; 436 } 437 else { 438 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 439 return; 440 } 441 break; 442 case GL_SOURCE0_RGB: 443 case GL_SOURCE1_RGB: 444 case GL_SOURCE2_RGB: 445 if (ctx->Extensions.EXT_texture_env_combine || 446 ctx->Extensions.ARB_texture_env_combine) { 447 const GLenum source = (GLenum) (GLint) *param; 448 const GLuint s = pname - GL_SOURCE0_RGB; 449 if (texUnit->Combine.SourceRGB[s] == source) 450 return; 451 if (source == GL_TEXTURE || 452 source == GL_CONSTANT || 453 source == GL_PRIMARY_COLOR || 454 source == GL_PREVIOUS || 455 (ctx->Extensions.ARB_texture_env_crossbar && 456 source >= GL_TEXTURE0 && 457 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) || 458 (ctx->Extensions.ATI_texture_env_combine3 && 459 (source == GL_ZERO || source == GL_ONE))) { 460 /* legal */ 461 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 462 texUnit->Combine.SourceRGB[s] = source; 463 } 464 else { 465 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source); 466 return; 467 } 468 } 469 else { 470 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 471 return; 472 } 473 break; 474 case GL_SOURCE0_ALPHA: 475 case GL_SOURCE1_ALPHA: 476 case GL_SOURCE2_ALPHA: 477 if (ctx->Extensions.EXT_texture_env_combine || 478 ctx->Extensions.ARB_texture_env_combine) { 479 const GLenum source = (GLenum) (GLint) *param; 480 const GLuint s = pname - GL_SOURCE0_ALPHA; 481 if (texUnit->Combine.SourceA[s] == source) 482 return; 483 if (source == GL_TEXTURE || 484 source == GL_CONSTANT || 485 source == GL_PRIMARY_COLOR || 486 source == GL_PREVIOUS || 487 (ctx->Extensions.ARB_texture_env_crossbar && 488 source >= GL_TEXTURE0 && 489 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) || 490 (ctx->Extensions.ATI_texture_env_combine3 && 491 (source == GL_ZERO || source == GL_ONE))) { 492 /* legal */ 493 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 494 texUnit->Combine.SourceA[s] = source; 495 } 496 else { 497 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source); 498 return; 499 } 500 } 501 else { 502 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 503 return; 504 } 505 break; 506 case GL_OPERAND0_RGB: 507 case GL_OPERAND1_RGB: 508 if (ctx->Extensions.EXT_texture_env_combine || 509 ctx->Extensions.ARB_texture_env_combine) { 510 const GLenum operand = (GLenum) (GLint) *param; 511 const GLuint s = pname - GL_OPERAND0_RGB; 512 if (texUnit->Combine.OperandRGB[s] == operand) 513 return; 514 switch (operand) { 515 case GL_SRC_COLOR: 516 case GL_ONE_MINUS_SRC_COLOR: 517 case GL_SRC_ALPHA: 518 case GL_ONE_MINUS_SRC_ALPHA: 519 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 520 texUnit->Combine.OperandRGB[s] = operand; 521 break; 522 default: 523 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); 524 return; 525 } 526 } 527 else { 528 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 529 return; 530 } 531 break; 532 case GL_OPERAND0_ALPHA: 533 case GL_OPERAND1_ALPHA: 534 if (ctx->Extensions.EXT_texture_env_combine || 535 ctx->Extensions.ARB_texture_env_combine) { 536 const GLenum operand = (GLenum) (GLint) *param; 537 if (texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] == operand) 538 return; 539 switch (operand) { 540 case GL_SRC_ALPHA: 541 case GL_ONE_MINUS_SRC_ALPHA: 542 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 543 texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] = operand; 544 break; 545 default: 546 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); 547 return; 548 } 549 } 550 else { 551 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 552 return; 553 } 554 break; 555 case GL_OPERAND2_RGB: 556 if (ctx->Extensions.ARB_texture_env_combine) { 557 const GLenum operand = (GLenum) (GLint) *param; 558 if (texUnit->Combine.OperandRGB[2] == operand) 559 return; 560 switch (operand) { 561 case GL_SRC_COLOR: /* ARB combine only */ 562 case GL_ONE_MINUS_SRC_COLOR: /* ARB combine only */ 563 case GL_SRC_ALPHA: 564 case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */ 565 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 566 texUnit->Combine.OperandRGB[2] = operand; 567 break; 568 default: 569 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); 570 return; 571 } 572 } 573 else if (ctx->Extensions.EXT_texture_env_combine) { 574 const GLenum operand = (GLenum) (GLint) *param; 575 if (texUnit->Combine.OperandRGB[2] == operand) 576 return; 577 /* operand must be GL_SRC_ALPHA which is the initial value - thus 578 don't need to actually compare the operand to the possible value */ 579 else { 580 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); 581 return; 582 } 583 } 584 else { 585 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 586 return; 587 } 588 break; 589 case GL_OPERAND2_ALPHA: 590 if (ctx->Extensions.ARB_texture_env_combine) { 591 const GLenum operand = (GLenum) (GLint) *param; 592 if (texUnit->Combine.OperandA[2] == operand) 593 return; 594 switch (operand) { 595 case GL_SRC_ALPHA: 596 case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */ 597 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 598 texUnit->Combine.OperandA[2] = operand; 599 break; 600 default: 601 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); 602 return; 603 } 604 } 605 else if (ctx->Extensions.EXT_texture_env_combine) { 606 const GLenum operand = (GLenum) (GLint) *param; 607 if (texUnit->Combine.OperandA[2] == operand) 608 return; 609 /* operand must be GL_SRC_ALPHA which is the initial value - thus 610 don't need to actually compare the operand to the possible value */ 611 else { 612 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); 613 return; 614 } 615 } 616 else { 617 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 618 return; 619 } 620 break; 621 case GL_RGB_SCALE: 622 if (ctx->Extensions.EXT_texture_env_combine || 623 ctx->Extensions.ARB_texture_env_combine) { 624 GLuint newshift; 625 if (*param == 1.0) { 626 newshift = 0; 627 } 628 else if (*param == 2.0) { 629 newshift = 1; 630 } 631 else if (*param == 4.0) { 632 newshift = 2; 633 } 634 else { 635 _mesa_error( ctx, GL_INVALID_VALUE, 636 "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" ); 637 return; 638 } 639 if (texUnit->Combine.ScaleShiftRGB == newshift) 640 return; 641 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 642 texUnit->Combine.ScaleShiftRGB = newshift; 643 } 644 else { 645 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 646 return; 647 } 648 break; 649 case GL_ALPHA_SCALE: 650 if (ctx->Extensions.EXT_texture_env_combine || 651 ctx->Extensions.ARB_texture_env_combine) { 652 GLuint newshift; 653 if (*param == 1.0) { 654 newshift = 0; 655 } 656 else if (*param == 2.0) { 657 newshift = 1; 658 } 659 else if (*param == 4.0) { 660 newshift = 2; 661 } 662 else { 663 _mesa_error( ctx, GL_INVALID_VALUE, 664 "glTexEnv(GL_ALPHA_SCALE not 1, 2 or 4)" ); 665 return; 666 } 667 if (texUnit->Combine.ScaleShiftA == newshift) 668 return; 669 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 670 texUnit->Combine.ScaleShiftA = newshift; 671 } 672 else { 673 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 674 return; 675 } 676 break; 677 default: 678 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" ); 679 return; 680 } 681 } 682 else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) { 683 /* GL_EXT_texture_lod_bias */ 684 if (!ctx->Extensions.EXT_texture_lod_bias) { 685 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target ); 686 return; 687 } 688 if (pname == GL_TEXTURE_LOD_BIAS_EXT) { 689 if (texUnit->LodBias == param[0]) 690 return; 691 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 692 texUnit->LodBias = param[0]; 693 } 694 else { 695 TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 696 return; 697 } 698 } 699 else if (target == GL_POINT_SPRITE_NV) { 700 /* GL_ARB_point_sprite / GL_NV_point_sprite */ 701 if (!ctx->Extensions.NV_point_sprite 702 && !ctx->Extensions.ARB_point_sprite) { 703 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target ); 704 return; 705 } 706 if (pname == GL_COORD_REPLACE_NV) { 707 const GLenum value = (GLenum) param[0]; 708 if (value == GL_TRUE || value == GL_FALSE) { 709 /* It's kind of weird to set point state via glTexEnv, 710 * but that's what the spec calls for. 711 */ 712 const GLboolean state = (GLboolean) value; 713 if (ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] == state) 714 return; 715 FLUSH_VERTICES(ctx, _NEW_POINT); 716 ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] = state; 717 } 718 else { 719 _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", value); 720 return; 721 } 722 } 723 else { 724 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname ); 725 return; 726 } 727 } 728 else { 729 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)",target ); 730 return; 731 } 732 733 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) 734 _mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n", 735 _mesa_lookup_enum_by_nr(target), 736 _mesa_lookup_enum_by_nr(pname), 737 *param, 738 _mesa_lookup_enum_by_nr((GLenum) (GLint) *param)); 739 740 /* Tell device driver about the new texture environment */ 741 if (ctx->Driver.TexEnv) { 742 (*ctx->Driver.TexEnv)( ctx, target, pname, param ); 743 } 744} 745 746 747void GLAPIENTRY 748_mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param ) 749{ 750 _mesa_TexEnvfv( target, pname, ¶m ); 751} 752 753 754 755void GLAPIENTRY 756_mesa_TexEnvi( GLenum target, GLenum pname, GLint param ) 757{ 758 GLfloat p[4]; 759 p[0] = (GLfloat) param; 760 p[1] = p[2] = p[3] = 0.0; 761 _mesa_TexEnvfv( target, pname, p ); 762} 763 764 765void GLAPIENTRY 766_mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param ) 767{ 768 GLfloat p[4]; 769 if (pname == GL_TEXTURE_ENV_COLOR) { 770 p[0] = INT_TO_FLOAT( param[0] ); 771 p[1] = INT_TO_FLOAT( param[1] ); 772 p[2] = INT_TO_FLOAT( param[2] ); 773 p[3] = INT_TO_FLOAT( param[3] ); 774 } 775 else { 776 p[0] = (GLfloat) param[0]; 777 p[1] = p[2] = p[3] = 0; /* init to zero, just to be safe */ 778 } 779 _mesa_TexEnvfv( target, pname, p ); 780} 781 782 783void GLAPIENTRY 784_mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) 785{ 786 GLuint maxUnit; 787 const struct gl_texture_unit *texUnit; 788 GET_CURRENT_CONTEXT(ctx); 789 ASSERT_OUTSIDE_BEGIN_END(ctx); 790 791 maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV) 792 ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits; 793 if (ctx->Texture.CurrentUnit >= maxUnit) { 794 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnvfv(current unit)"); 795 return; 796 } 797 798 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 799 800 if (target == GL_TEXTURE_ENV) { 801 switch (pname) { 802 case GL_TEXTURE_ENV_MODE: 803 *params = ENUM_TO_FLOAT(texUnit->EnvMode); 804 break; 805 case GL_TEXTURE_ENV_COLOR: 806 COPY_4FV( params, texUnit->EnvColor ); 807 break; 808 case GL_COMBINE_RGB: 809 if (ctx->Extensions.EXT_texture_env_combine || 810 ctx->Extensions.ARB_texture_env_combine) { 811 *params = (GLfloat) texUnit->Combine.ModeRGB; 812 } 813 else { 814 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 815 } 816 break; 817 case GL_COMBINE_ALPHA: 818 if (ctx->Extensions.EXT_texture_env_combine || 819 ctx->Extensions.ARB_texture_env_combine) { 820 *params = (GLfloat) texUnit->Combine.ModeA; 821 } 822 else { 823 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 824 } 825 break; 826 case GL_SOURCE0_RGB: 827 case GL_SOURCE1_RGB: 828 case GL_SOURCE2_RGB: 829 if (ctx->Extensions.EXT_texture_env_combine || 830 ctx->Extensions.ARB_texture_env_combine) { 831 const unsigned rgb_idx = pname - GL_SOURCE0_RGB; 832 *params = (GLfloat) texUnit->Combine.SourceRGB[rgb_idx]; 833 } 834 else { 835 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 836 } 837 break; 838 case GL_SOURCE0_ALPHA: 839 case GL_SOURCE1_ALPHA: 840 case GL_SOURCE2_ALPHA: 841 if (ctx->Extensions.EXT_texture_env_combine || 842 ctx->Extensions.ARB_texture_env_combine) { 843 const unsigned alpha_idx = pname - GL_SOURCE0_ALPHA; 844 *params = (GLfloat) texUnit->Combine.SourceA[alpha_idx]; 845 } 846 else { 847 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 848 } 849 break; 850 case GL_OPERAND0_RGB: 851 case GL_OPERAND1_RGB: 852 case GL_OPERAND2_RGB: 853 if (ctx->Extensions.EXT_texture_env_combine || 854 ctx->Extensions.ARB_texture_env_combine) { 855 const unsigned op_rgb = pname - GL_OPERAND0_RGB; 856 *params = (GLfloat) texUnit->Combine.OperandRGB[op_rgb]; 857 } 858 else { 859 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 860 } 861 break; 862 case GL_OPERAND0_ALPHA: 863 case GL_OPERAND1_ALPHA: 864 case GL_OPERAND2_ALPHA: 865 if (ctx->Extensions.EXT_texture_env_combine || 866 ctx->Extensions.ARB_texture_env_combine) { 867 const unsigned op_alpha = pname - GL_OPERAND0_ALPHA; 868 *params = (GLfloat) texUnit->Combine.OperandA[op_alpha]; 869 } 870 else { 871 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 872 } 873 break; 874 case GL_RGB_SCALE: 875 if (ctx->Extensions.EXT_texture_env_combine || 876 ctx->Extensions.ARB_texture_env_combine) { 877 if (texUnit->Combine.ScaleShiftRGB == 0) 878 *params = 1.0; 879 else if (texUnit->Combine.ScaleShiftRGB == 1) 880 *params = 2.0; 881 else 882 *params = 4.0; 883 } 884 else { 885 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 886 return; 887 } 888 break; 889 case GL_ALPHA_SCALE: 890 if (ctx->Extensions.EXT_texture_env_combine || 891 ctx->Extensions.ARB_texture_env_combine) { 892 if (texUnit->Combine.ScaleShiftA == 0) 893 *params = 1.0; 894 else if (texUnit->Combine.ScaleShiftA == 1) 895 *params = 2.0; 896 else 897 *params = 4.0; 898 } 899 else { 900 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 901 return; 902 } 903 break; 904 default: 905 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname=0x%x)", pname); 906 } 907 } 908 else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) { 909 /* GL_EXT_texture_lod_bias */ 910 if (!ctx->Extensions.EXT_texture_lod_bias) { 911 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" ); 912 return; 913 } 914 if (pname == GL_TEXTURE_LOD_BIAS_EXT) { 915 *params = texUnit->LodBias; 916 } 917 else { 918 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" ); 919 return; 920 } 921 } 922 else if (target == GL_POINT_SPRITE_NV) { 923 /* GL_ARB_point_sprite / GL_NV_point_sprite */ 924 if (!ctx->Extensions.NV_point_sprite 925 && !ctx->Extensions.ARB_point_sprite) { 926 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" ); 927 return; 928 } 929 if (pname == GL_COORD_REPLACE_NV) { 930 *params = (GLfloat) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit]; 931 } 932 else { 933 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" ); 934 return; 935 } 936 } 937 else { 938 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" ); 939 return; 940 } 941} 942 943 944void GLAPIENTRY 945_mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) 946{ 947 GLuint maxUnit; 948 const struct gl_texture_unit *texUnit; 949 GET_CURRENT_CONTEXT(ctx); 950 ASSERT_OUTSIDE_BEGIN_END(ctx); 951 952 maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV) 953 ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits; 954 if (ctx->Texture.CurrentUnit >= maxUnit) { 955 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnviv(current unit)"); 956 return; 957 } 958 959 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 960 961 if (target == GL_TEXTURE_ENV) { 962 switch (pname) { 963 case GL_TEXTURE_ENV_MODE: 964 *params = (GLint) texUnit->EnvMode; 965 break; 966 case GL_TEXTURE_ENV_COLOR: 967 params[0] = FLOAT_TO_INT( texUnit->EnvColor[0] ); 968 params[1] = FLOAT_TO_INT( texUnit->EnvColor[1] ); 969 params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] ); 970 params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] ); 971 break; 972 case GL_COMBINE_RGB: 973 if (ctx->Extensions.EXT_texture_env_combine || 974 ctx->Extensions.ARB_texture_env_combine) { 975 *params = (GLint) texUnit->Combine.ModeRGB; 976 } 977 else { 978 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); 979 } 980 break; 981 case GL_COMBINE_ALPHA: 982 if (ctx->Extensions.EXT_texture_env_combine || 983 ctx->Extensions.ARB_texture_env_combine) { 984 *params = (GLint) texUnit->Combine.ModeA; 985 } 986 else { 987 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); 988 } 989 break; 990 case GL_SOURCE0_RGB: 991 case GL_SOURCE1_RGB: 992 case GL_SOURCE2_RGB: 993 if (ctx->Extensions.EXT_texture_env_combine || 994 ctx->Extensions.ARB_texture_env_combine) { 995 const unsigned rgb_idx = pname - GL_SOURCE0_RGB; 996 *params = (GLint) texUnit->Combine.SourceRGB[rgb_idx]; 997 } 998 else { 999 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); 1000 } 1001 break; 1002 case GL_SOURCE0_ALPHA: 1003 case GL_SOURCE1_ALPHA: 1004 case GL_SOURCE2_ALPHA: 1005 if (ctx->Extensions.EXT_texture_env_combine || 1006 ctx->Extensions.ARB_texture_env_combine) { 1007 const unsigned alpha_idx = pname - GL_SOURCE0_ALPHA; 1008 *params = (GLint) texUnit->Combine.SourceA[alpha_idx]; 1009 } 1010 else { 1011 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); 1012 } 1013 break; 1014 case GL_OPERAND0_RGB: 1015 case GL_OPERAND1_RGB: 1016 case GL_OPERAND2_RGB: 1017 if (ctx->Extensions.EXT_texture_env_combine || 1018 ctx->Extensions.ARB_texture_env_combine) { 1019 const unsigned op_rgb = pname - GL_OPERAND0_RGB; 1020 *params = (GLint) texUnit->Combine.OperandRGB[op_rgb]; 1021 } 1022 else { 1023 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); 1024 } 1025 break; 1026 case GL_OPERAND0_ALPHA: 1027 case GL_OPERAND1_ALPHA: 1028 case GL_OPERAND2_ALPHA: 1029 if (ctx->Extensions.EXT_texture_env_combine || 1030 ctx->Extensions.ARB_texture_env_combine) { 1031 const unsigned op_alpha = pname - GL_OPERAND0_ALPHA; 1032 *params = (GLint) texUnit->Combine.OperandA[op_alpha]; 1033 } 1034 else { 1035 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); 1036 } 1037 break; 1038 case GL_RGB_SCALE: 1039 if (ctx->Extensions.EXT_texture_env_combine || 1040 ctx->Extensions.ARB_texture_env_combine) { 1041 if (texUnit->Combine.ScaleShiftRGB == 0) 1042 *params = 1; 1043 else if (texUnit->Combine.ScaleShiftRGB == 1) 1044 *params = 2; 1045 else 1046 *params = 4; 1047 } 1048 else { 1049 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); 1050 return; 1051 } 1052 break; 1053 case GL_ALPHA_SCALE: 1054 if (ctx->Extensions.EXT_texture_env_combine || 1055 ctx->Extensions.ARB_texture_env_combine) { 1056 if (texUnit->Combine.ScaleShiftA == 0) 1057 *params = 1; 1058 else if (texUnit->Combine.ScaleShiftA == 1) 1059 *params = 2; 1060 else 1061 *params = 4; 1062 } 1063 else { 1064 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); 1065 return; 1066 } 1067 break; 1068 default: 1069 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname=0x%x)", 1070 pname); 1071 } 1072 } 1073 else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) { 1074 /* GL_EXT_texture_lod_bias */ 1075 if (!ctx->Extensions.EXT_texture_lod_bias) { 1076 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" ); 1077 return; 1078 } 1079 if (pname == GL_TEXTURE_LOD_BIAS_EXT) { 1080 *params = (GLint) texUnit->LodBias; 1081 } 1082 else { 1083 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" ); 1084 return; 1085 } 1086 } 1087 else if (target == GL_POINT_SPRITE_NV) { 1088 /* GL_ARB_point_sprite / GL_NV_point_sprite */ 1089 if (!ctx->Extensions.NV_point_sprite 1090 && !ctx->Extensions.ARB_point_sprite) { 1091 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" ); 1092 return; 1093 } 1094 if (pname == GL_COORD_REPLACE_NV) { 1095 *params = (GLint) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit]; 1096 } 1097 else { 1098 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" ); 1099 return; 1100 } 1101 } 1102 else { 1103 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" ); 1104 return; 1105 } 1106} 1107 1108 1109 1110 1111/**********************************************************************/ 1112/* Texture Parameters */ 1113/**********************************************************************/ 1114 1115static GLboolean 1116_mesa_validate_texture_wrap_mode(GLcontext * ctx, 1117 GLenum target, GLenum eparam) 1118{ 1119 const struct gl_extensions * const e = & ctx->Extensions; 1120 1121 if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE || 1122 (eparam == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) { 1123 /* any texture target */ 1124 return GL_TRUE; 1125 } 1126 else if (target != GL_TEXTURE_RECTANGLE_NV && 1127 (eparam == GL_REPEAT || 1128 (eparam == GL_MIRRORED_REPEAT && 1129 e->ARB_texture_mirrored_repeat) || 1130 (eparam == GL_MIRROR_CLAMP_EXT && 1131 (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) || 1132 (eparam == GL_MIRROR_CLAMP_TO_EDGE_EXT && 1133 (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) || 1134 (eparam == GL_MIRROR_CLAMP_TO_BORDER_EXT && 1135 (e->EXT_texture_mirror_clamp)))) { 1136 /* non-rectangle texture */ 1137 return GL_TRUE; 1138 } 1139 1140 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); 1141 return GL_FALSE; 1142} 1143 1144 1145void GLAPIENTRY 1146_mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param ) 1147{ 1148 _mesa_TexParameterfv(target, pname, ¶m); 1149} 1150 1151 1152void GLAPIENTRY 1153_mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ) 1154{ 1155 const GLenum eparam = (GLenum) (GLint) params[0]; 1156 struct gl_texture_unit *texUnit; 1157 struct gl_texture_object *texObj; 1158 GET_CURRENT_CONTEXT(ctx); 1159 ASSERT_OUTSIDE_BEGIN_END(ctx); 1160 1161 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) 1162 _mesa_debug(ctx, "glTexParameter %s %s %.1f(%s)...\n", 1163 _mesa_lookup_enum_by_nr(target), 1164 _mesa_lookup_enum_by_nr(pname), 1165 *params, 1166 _mesa_lookup_enum_by_nr(eparam)); 1167 1168 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { 1169 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameterfv(current unit)"); 1170 return; 1171 } 1172 1173 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1174 1175 switch (target) { 1176 case GL_TEXTURE_1D: 1177 texObj = texUnit->Current1D; 1178 break; 1179 case GL_TEXTURE_2D: 1180 texObj = texUnit->Current2D; 1181 break; 1182 case GL_TEXTURE_3D: 1183 texObj = texUnit->Current3D; 1184 break; 1185 case GL_TEXTURE_CUBE_MAP: 1186 if (!ctx->Extensions.ARB_texture_cube_map) { 1187 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" ); 1188 return; 1189 } 1190 texObj = texUnit->CurrentCubeMap; 1191 break; 1192 case GL_TEXTURE_RECTANGLE_NV: 1193 if (!ctx->Extensions.NV_texture_rectangle) { 1194 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" ); 1195 return; 1196 } 1197 texObj = texUnit->CurrentRect; 1198 break; 1199 default: 1200 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" ); 1201 return; 1202 } 1203 1204 switch (pname) { 1205 case GL_TEXTURE_MIN_FILTER: 1206 /* A small optimization */ 1207 if (texObj->MinFilter == eparam) 1208 return; 1209 if (eparam==GL_NEAREST || eparam==GL_LINEAR) { 1210 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1211 texObj->MinFilter = eparam; 1212 } 1213 else if ((eparam==GL_NEAREST_MIPMAP_NEAREST || 1214 eparam==GL_LINEAR_MIPMAP_NEAREST || 1215 eparam==GL_NEAREST_MIPMAP_LINEAR || 1216 eparam==GL_LINEAR_MIPMAP_LINEAR) && 1217 texObj->Target != GL_TEXTURE_RECTANGLE_NV) { 1218 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1219 texObj->MinFilter = eparam; 1220 } 1221 else { 1222 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); 1223 return; 1224 } 1225 break; 1226 case GL_TEXTURE_MAG_FILTER: 1227 /* A small optimization */ 1228 if (texObj->MagFilter == eparam) 1229 return; 1230 1231 if (eparam==GL_NEAREST || eparam==GL_LINEAR) { 1232 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1233 texObj->MagFilter = eparam; 1234 } 1235 else { 1236 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); 1237 return; 1238 } 1239 break; 1240 case GL_TEXTURE_WRAP_S: 1241 if (texObj->WrapS == eparam) 1242 return; 1243 if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) { 1244 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1245 texObj->WrapS = eparam; 1246 } 1247 else { 1248 return; 1249 } 1250 break; 1251 case GL_TEXTURE_WRAP_T: 1252 if (texObj->WrapT == eparam) 1253 return; 1254 if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) { 1255 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1256 texObj->WrapT = eparam; 1257 } 1258 else { 1259 return; 1260 } 1261 break; 1262 case GL_TEXTURE_WRAP_R: 1263 if (texObj->WrapR == eparam) 1264 return; 1265 if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) { 1266 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1267 texObj->WrapR = eparam; 1268 } 1269 else { 1270 return; 1271 } 1272 break; 1273 case GL_TEXTURE_BORDER_COLOR: 1274 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1275 texObj->BorderColor[RCOMP] = params[0]; 1276 texObj->BorderColor[GCOMP] = params[1]; 1277 texObj->BorderColor[BCOMP] = params[2]; 1278 texObj->BorderColor[ACOMP] = params[3]; 1279 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[RCOMP], params[0]); 1280 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[GCOMP], params[1]); 1281 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[BCOMP], params[2]); 1282 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[ACOMP], params[3]); 1283 break; 1284 case GL_TEXTURE_MIN_LOD: 1285 if (texObj->MinLod == params[0]) 1286 return; 1287 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1288 texObj->MinLod = params[0]; 1289 break; 1290 case GL_TEXTURE_MAX_LOD: 1291 if (texObj->MaxLod == params[0]) 1292 return; 1293 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1294 texObj->MaxLod = params[0]; 1295 break; 1296 case GL_TEXTURE_BASE_LEVEL: 1297 if (params[0] < 0.0) { 1298 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)"); 1299 return; 1300 } 1301 if (target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0.0) { 1302 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)"); 1303 return; 1304 } 1305 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1306 texObj->BaseLevel = (GLint) params[0]; 1307 break; 1308 case GL_TEXTURE_MAX_LEVEL: 1309 if (params[0] < 0.0) { 1310 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)"); 1311 return; 1312 } 1313 if (target == GL_TEXTURE_RECTANGLE_ARB) { 1314 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(param)"); 1315 return; 1316 } 1317 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1318 texObj->MaxLevel = (GLint) params[0]; 1319 break; 1320 case GL_TEXTURE_PRIORITY: 1321 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1322 texObj->Priority = CLAMP( params[0], 0.0F, 1.0F ); 1323 break; 1324 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1325 if (ctx->Extensions.EXT_texture_filter_anisotropic) { 1326 if (params[0] < 1.0) { 1327 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); 1328 return; 1329 } 1330 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1331 /* clamp to max, that's what NVIDIA does */ 1332 texObj->MaxAnisotropy = MIN2(params[0], 1333 ctx->Const.MaxTextureMaxAnisotropy); 1334 } 1335 else { 1336 _mesa_error(ctx, GL_INVALID_ENUM, 1337 "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)"); 1338 return; 1339 } 1340 break; 1341 case GL_TEXTURE_COMPARE_SGIX: 1342 if (ctx->Extensions.SGIX_shadow) { 1343 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1344 texObj->CompareFlag = params[0] ? GL_TRUE : GL_FALSE; 1345 } 1346 else { 1347 _mesa_error(ctx, GL_INVALID_ENUM, 1348 "glTexParameter(pname=GL_TEXTURE_COMPARE_SGIX)"); 1349 return; 1350 } 1351 break; 1352 case GL_TEXTURE_COMPARE_OPERATOR_SGIX: 1353 if (ctx->Extensions.SGIX_shadow) { 1354 GLenum op = (GLenum) params[0]; 1355 if (op == GL_TEXTURE_LEQUAL_R_SGIX || 1356 op == GL_TEXTURE_GEQUAL_R_SGIX) { 1357 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1358 texObj->CompareOperator = op; 1359 } 1360 else { 1361 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)"); 1362 } 1363 } 1364 else { 1365 _mesa_error(ctx, GL_INVALID_ENUM, 1366 "glTexParameter(pname=GL_TEXTURE_COMPARE_OPERATOR_SGIX)"); 1367 return; 1368 } 1369 break; 1370 case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */ 1371 if (ctx->Extensions.SGIX_shadow_ambient) { 1372 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1373 texObj->ShadowAmbient = CLAMP(params[0], 0.0F, 1.0F); 1374 } 1375 else { 1376 _mesa_error(ctx, GL_INVALID_ENUM, 1377 "glTexParameter(pname=GL_SHADOW_AMBIENT_SGIX)"); 1378 return; 1379 } 1380 break; 1381 case GL_GENERATE_MIPMAP_SGIS: 1382 if (ctx->Extensions.SGIS_generate_mipmap) { 1383 texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE; 1384 } 1385 else { 1386 _mesa_error(ctx, GL_INVALID_ENUM, 1387 "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)"); 1388 return; 1389 } 1390 break; 1391 case GL_TEXTURE_COMPARE_MODE_ARB: 1392 if (ctx->Extensions.ARB_shadow) { 1393 const GLenum mode = (GLenum) params[0]; 1394 if (mode == GL_NONE || mode == GL_COMPARE_R_TO_TEXTURE_ARB) { 1395 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1396 texObj->CompareMode = mode; 1397 } 1398 else { 1399 _mesa_error(ctx, GL_INVALID_ENUM, 1400 "glTexParameter(bad GL_TEXTURE_COMPARE_MODE_ARB: 0x%x)", mode); 1401 return; 1402 } 1403 } 1404 else { 1405 _mesa_error(ctx, GL_INVALID_ENUM, 1406 "glTexParameter(pname=GL_TEXTURE_COMPARE_MODE_ARB)"); 1407 return; 1408 } 1409 break; 1410 case GL_TEXTURE_COMPARE_FUNC_ARB: 1411 if (ctx->Extensions.ARB_shadow) { 1412 const GLenum func = (GLenum) params[0]; 1413 if (func == GL_LEQUAL || func == GL_GEQUAL) { 1414 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1415 texObj->CompareFunc = func; 1416 } 1417 else if (ctx->Extensions.EXT_shadow_funcs && 1418 (func == GL_EQUAL || 1419 func == GL_NOTEQUAL || 1420 func == GL_LESS || 1421 func == GL_GREATER || 1422 func == GL_ALWAYS || 1423 func == GL_NEVER)) { 1424 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1425 texObj->CompareFunc = func; 1426 } 1427 else { 1428 _mesa_error(ctx, GL_INVALID_ENUM, 1429 "glTexParameter(bad GL_TEXTURE_COMPARE_FUNC_ARB)"); 1430 return; 1431 } 1432 } 1433 else { 1434 _mesa_error(ctx, GL_INVALID_ENUM, 1435 "glTexParameter(pname=GL_TEXTURE_COMPARE_FUNC_ARB)"); 1436 return; 1437 } 1438 break; 1439 case GL_DEPTH_TEXTURE_MODE_ARB: 1440 if (ctx->Extensions.ARB_depth_texture) { 1441 const GLenum result = (GLenum) params[0]; 1442 if (result == GL_LUMINANCE || result == GL_INTENSITY 1443 || result == GL_ALPHA) { 1444 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1445 texObj->DepthMode = result; 1446 } 1447 else { 1448 _mesa_error(ctx, GL_INVALID_ENUM, 1449 "glTexParameter(bad GL_DEPTH_TEXTURE_MODE_ARB)"); 1450 return; 1451 } 1452 } 1453 else { 1454 _mesa_error(ctx, GL_INVALID_ENUM, 1455 "glTexParameter(pname=GL_DEPTH_TEXTURE_MODE_ARB)"); 1456 return; 1457 } 1458 break; 1459 case GL_TEXTURE_LOD_BIAS: 1460 /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias*/ 1461 if (ctx->Extensions.EXT_texture_lod_bias) { 1462 if (texObj->LodBias != params[0]) { 1463 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1464 texObj->LodBias = params[0]; 1465 } 1466 } 1467 break; 1468 1469 default: 1470 _mesa_error(ctx, GL_INVALID_ENUM, 1471 "glTexParameter(pname=0x%x)", pname); 1472 return; 1473 } 1474 1475 texObj->Complete = GL_FALSE; 1476 1477 if (ctx->Driver.TexParameter) { 1478 (*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params ); 1479 } 1480} 1481 1482 1483void GLAPIENTRY 1484_mesa_TexParameteri( GLenum target, GLenum pname, GLint param ) 1485{ 1486 GLfloat fparam[4]; 1487 if (pname == GL_TEXTURE_PRIORITY) 1488 fparam[0] = INT_TO_FLOAT(param); 1489 else 1490 fparam[0] = (GLfloat) param; 1491 fparam[1] = fparam[2] = fparam[3] = 0.0; 1492 _mesa_TexParameterfv(target, pname, fparam); 1493} 1494 1495 1496void GLAPIENTRY 1497_mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params ) 1498{ 1499 GLfloat fparam[4]; 1500 if (pname == GL_TEXTURE_BORDER_COLOR) { 1501 fparam[0] = INT_TO_FLOAT(params[0]); 1502 fparam[1] = INT_TO_FLOAT(params[1]); 1503 fparam[2] = INT_TO_FLOAT(params[2]); 1504 fparam[3] = INT_TO_FLOAT(params[3]); 1505 } 1506 else { 1507 if (pname == GL_TEXTURE_PRIORITY) 1508 fparam[0] = INT_TO_FLOAT(params[0]); 1509 else 1510 fparam[0] = (GLfloat) params[0]; 1511 fparam[1] = fparam[2] = fparam[3] = 0.0F; 1512 } 1513 _mesa_TexParameterfv(target, pname, fparam); 1514} 1515 1516 1517void GLAPIENTRY 1518_mesa_GetTexLevelParameterfv( GLenum target, GLint level, 1519 GLenum pname, GLfloat *params ) 1520{ 1521 GLint iparam; 1522 _mesa_GetTexLevelParameteriv( target, level, pname, &iparam ); 1523 *params = (GLfloat) iparam; 1524} 1525 1526 1527static GLuint 1528tex_image_dimensions(GLcontext *ctx, GLenum target) 1529{ 1530 switch (target) { 1531 case GL_TEXTURE_1D: 1532 case GL_PROXY_TEXTURE_1D: 1533 return 1; 1534 case GL_TEXTURE_2D: 1535 case GL_PROXY_TEXTURE_2D: 1536 return 2; 1537 case GL_TEXTURE_3D: 1538 case GL_PROXY_TEXTURE_3D: 1539 return 3; 1540 case GL_TEXTURE_CUBE_MAP: 1541 case GL_PROXY_TEXTURE_CUBE_MAP: 1542 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1543 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1544 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1545 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1546 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1547 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1548 return ctx->Extensions.ARB_texture_cube_map ? 2 : 0; 1549 case GL_TEXTURE_RECTANGLE_NV: 1550 case GL_PROXY_TEXTURE_RECTANGLE_NV: 1551 return ctx->Extensions.NV_texture_rectangle ? 2 : 0; 1552 default: 1553 _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()"); 1554 return 0; 1555 } 1556} 1557 1558 1559void GLAPIENTRY 1560_mesa_GetTexLevelParameteriv( GLenum target, GLint level, 1561 GLenum pname, GLint *params ) 1562{ 1563 const struct gl_texture_unit *texUnit; 1564 struct gl_texture_object *texObj; 1565 const struct gl_texture_image *img = NULL; 1566 GLuint dimensions; 1567 GLboolean isProxy; 1568 GLint maxLevels; 1569 GET_CURRENT_CONTEXT(ctx); 1570 ASSERT_OUTSIDE_BEGIN_END(ctx); 1571 1572 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { 1573 _mesa_error(ctx, GL_INVALID_OPERATION, 1574 "glGetTexLevelParameteriv(current unit)"); 1575 return; 1576 } 1577 1578 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1579 1580 /* this will catch bad target values */ 1581 dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */ 1582 if (dimensions == 0) { 1583 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)"); 1584 return; 1585 } 1586 1587 maxLevels = _mesa_max_texture_levels(ctx, target); 1588 if (maxLevels == 0) { 1589 /* should not happen since <target> was just checked above */ 1590 _mesa_problem(ctx, "maxLevels=0 in _mesa_GetTexLevelParameter"); 1591 return; 1592 } 1593 1594 if (level < 0 || level >= maxLevels) { 1595 _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" ); 1596 return; 1597 } 1598 1599 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1600 _mesa_lock_texture(ctx, texObj); 1601 1602 img = _mesa_select_tex_image(ctx, texObj, target, level); 1603 if (!img || !img->TexFormat) { 1604 /* undefined texture image */ 1605 if (pname == GL_TEXTURE_COMPONENTS) 1606 *params = 1; 1607 else 1608 *params = 0; 1609 goto out; 1610 } 1611 1612 isProxy = _mesa_is_proxy_texture(target); 1613 1614 switch (pname) { 1615 case GL_TEXTURE_WIDTH: 1616 *params = img->Width; 1617 break; 1618 case GL_TEXTURE_HEIGHT: 1619 *params = img->Height; 1620 break; 1621 case GL_TEXTURE_DEPTH: 1622 *params = img->Depth; 1623 break; 1624 case GL_TEXTURE_INTERNAL_FORMAT: 1625 *params = img->InternalFormat; 1626 break; 1627 case GL_TEXTURE_BORDER: 1628 *params = img->Border; 1629 break; 1630 case GL_TEXTURE_RED_SIZE: 1631 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) 1632 *params = img->TexFormat->RedBits; 1633 else 1634 *params = 0; 1635 break; 1636 case GL_TEXTURE_GREEN_SIZE: 1637 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) 1638 *params = img->TexFormat->GreenBits; 1639 else 1640 *params = 0; 1641 break; 1642 case GL_TEXTURE_BLUE_SIZE: 1643 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) 1644 *params = img->TexFormat->BlueBits; 1645 else 1646 *params = 0; 1647 break; 1648 case GL_TEXTURE_ALPHA_SIZE: 1649 if (img->_BaseFormat == GL_ALPHA || 1650 img->_BaseFormat == GL_LUMINANCE_ALPHA || 1651 img->_BaseFormat == GL_RGBA) 1652 *params = img->TexFormat->AlphaBits; 1653 else 1654 *params = 0; 1655 break; 1656 case GL_TEXTURE_INTENSITY_SIZE: 1657 if (img->_BaseFormat != GL_INTENSITY) 1658 *params = 0; 1659 else if (img->TexFormat->IntensityBits > 0) 1660 *params = img->TexFormat->IntensityBits; 1661 else /* intensity probably stored as rgb texture */ 1662 *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits); 1663 break; 1664 case GL_TEXTURE_LUMINANCE_SIZE: 1665 if (img->_BaseFormat != GL_LUMINANCE && 1666 img->_BaseFormat != GL_LUMINANCE_ALPHA) 1667 *params = 0; 1668 else if (img->TexFormat->LuminanceBits > 0) 1669 *params = img->TexFormat->LuminanceBits; 1670 else /* luminance probably stored as rgb texture */ 1671 *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits); 1672 break; 1673 case GL_TEXTURE_INDEX_SIZE_EXT: 1674 if (img->_BaseFormat == GL_COLOR_INDEX) 1675 *params = img->TexFormat->IndexBits; 1676 else 1677 *params = 0; 1678 break; 1679 case GL_TEXTURE_DEPTH_SIZE_ARB: 1680 if (ctx->Extensions.SGIX_depth_texture || 1681 ctx->Extensions.ARB_depth_texture) 1682 *params = img->TexFormat->DepthBits; 1683 else 1684 _mesa_error(ctx, GL_INVALID_ENUM, 1685 "glGetTexLevelParameter[if]v(pname)"); 1686 break; 1687 case GL_TEXTURE_STENCIL_SIZE_EXT: 1688 if (ctx->Extensions.EXT_packed_depth_stencil) { 1689 *params = img->TexFormat->StencilBits; 1690 } 1691 else { 1692 _mesa_error(ctx, GL_INVALID_ENUM, 1693 "glGetTexLevelParameter[if]v(pname)"); 1694 } 1695 break; 1696 1697 /* GL_ARB_texture_compression */ 1698 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: 1699 if (ctx->Extensions.ARB_texture_compression) { 1700 if (img->IsCompressed && !isProxy) { 1701 /* Don't use ctx->Driver.CompressedTextureSize() since that 1702 * may returned a padded hardware size. 1703 */ 1704 *params = _mesa_compressed_texture_size(ctx, img->Width, 1705 img->Height, img->Depth, 1706 img->TexFormat->MesaFormat); 1707 } 1708 else { 1709 _mesa_error(ctx, GL_INVALID_OPERATION, 1710 "glGetTexLevelParameter[if]v(pname)"); 1711 } 1712 } 1713 else { 1714 _mesa_error(ctx, GL_INVALID_ENUM, 1715 "glGetTexLevelParameter[if]v(pname)"); 1716 } 1717 break; 1718 case GL_TEXTURE_COMPRESSED: 1719 if (ctx->Extensions.ARB_texture_compression) { 1720 *params = (GLint) img->IsCompressed; 1721 } 1722 else { 1723 _mesa_error(ctx, GL_INVALID_ENUM, 1724 "glGetTexLevelParameter[if]v(pname)"); 1725 } 1726 break; 1727 1728 /* GL_ARB_texture_float */ 1729 case GL_TEXTURE_RED_TYPE_ARB: 1730 if (ctx->Extensions.ARB_texture_float) { 1731 *params = img->TexFormat->RedBits ? img->TexFormat->DataType : GL_NONE; 1732 } 1733 else { 1734 _mesa_error(ctx, GL_INVALID_ENUM, 1735 "glGetTexLevelParameter[if]v(pname)"); 1736 } 1737 break; 1738 case GL_TEXTURE_GREEN_TYPE_ARB: 1739 if (ctx->Extensions.ARB_texture_float) { 1740 *params = img->TexFormat->GreenBits ? img->TexFormat->DataType : GL_NONE; 1741 } 1742 else { 1743 _mesa_error(ctx, GL_INVALID_ENUM, 1744 "glGetTexLevelParameter[if]v(pname)"); 1745 } 1746 break; 1747 case GL_TEXTURE_BLUE_TYPE_ARB: 1748 if (ctx->Extensions.ARB_texture_float) { 1749 *params = img->TexFormat->BlueBits ? img->TexFormat->DataType : GL_NONE; 1750 } 1751 else { 1752 _mesa_error(ctx, GL_INVALID_ENUM, 1753 "glGetTexLevelParameter[if]v(pname)"); 1754 } 1755 break; 1756 case GL_TEXTURE_ALPHA_TYPE_ARB: 1757 if (ctx->Extensions.ARB_texture_float) { 1758 *params = img->TexFormat->AlphaBits ? img->TexFormat->DataType : GL_NONE; 1759 } 1760 else { 1761 _mesa_error(ctx, GL_INVALID_ENUM, 1762 "glGetTexLevelParameter[if]v(pname)"); 1763 } 1764 break; 1765 case GL_TEXTURE_LUMINANCE_TYPE_ARB: 1766 if (ctx->Extensions.ARB_texture_float) { 1767 *params = img->TexFormat->LuminanceBits ? img->TexFormat->DataType : GL_NONE; 1768 } 1769 else { 1770 _mesa_error(ctx, GL_INVALID_ENUM, 1771 "glGetTexLevelParameter[if]v(pname)"); 1772 } 1773 break; 1774 case GL_TEXTURE_INTENSITY_TYPE_ARB: 1775 if (ctx->Extensions.ARB_texture_float) { 1776 *params = img->TexFormat->IntensityBits ? img->TexFormat->DataType : GL_NONE; 1777 } 1778 else { 1779 _mesa_error(ctx, GL_INVALID_ENUM, 1780 "glGetTexLevelParameter[if]v(pname)"); 1781 } 1782 break; 1783 case GL_TEXTURE_DEPTH_TYPE_ARB: 1784 if (ctx->Extensions.ARB_texture_float) { 1785 *params = img->TexFormat->DepthBits ? img->TexFormat->DataType : GL_NONE; 1786 } 1787 else { 1788 _mesa_error(ctx, GL_INVALID_ENUM, 1789 "glGetTexLevelParameter[if]v(pname)"); 1790 } 1791 break; 1792 1793 default: 1794 _mesa_error(ctx, GL_INVALID_ENUM, 1795 "glGetTexLevelParameter[if]v(pname)"); 1796 } 1797 1798 out: 1799 _mesa_unlock_texture(ctx, texObj); 1800} 1801 1802 1803 1804void GLAPIENTRY 1805_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) 1806{ 1807 struct gl_texture_unit *texUnit; 1808 struct gl_texture_object *obj; 1809 GLboolean error = GL_FALSE; 1810 GET_CURRENT_CONTEXT(ctx); 1811 ASSERT_OUTSIDE_BEGIN_END(ctx); 1812 1813 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { 1814 _mesa_error(ctx, GL_INVALID_OPERATION, 1815 "glGetTexParameterfv(current unit)"); 1816 return; 1817 } 1818 1819 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1820 1821 obj = _mesa_select_tex_object(ctx, texUnit, target); 1822 if (!obj) { 1823 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)"); 1824 return; 1825 } 1826 1827 _mesa_lock_texture(ctx, obj); 1828 switch (pname) { 1829 case GL_TEXTURE_MAG_FILTER: 1830 *params = ENUM_TO_FLOAT(obj->MagFilter); 1831 break; 1832 case GL_TEXTURE_MIN_FILTER: 1833 *params = ENUM_TO_FLOAT(obj->MinFilter); 1834 break; 1835 case GL_TEXTURE_WRAP_S: 1836 *params = ENUM_TO_FLOAT(obj->WrapS); 1837 break; 1838 case GL_TEXTURE_WRAP_T: 1839 *params = ENUM_TO_FLOAT(obj->WrapT); 1840 break; 1841 case GL_TEXTURE_WRAP_R: 1842 *params = ENUM_TO_FLOAT(obj->WrapR); 1843 break; 1844 case GL_TEXTURE_BORDER_COLOR: 1845 params[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F); 1846 params[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F); 1847 params[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F); 1848 params[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F); 1849 break; 1850 case GL_TEXTURE_RESIDENT: 1851 { 1852 GLboolean resident; 1853 if (ctx->Driver.IsTextureResident) 1854 resident = ctx->Driver.IsTextureResident(ctx, obj); 1855 else 1856 resident = GL_TRUE; 1857 *params = ENUM_TO_FLOAT(resident); 1858 } 1859 break; 1860 case GL_TEXTURE_PRIORITY: 1861 *params = obj->Priority; 1862 break; 1863 case GL_TEXTURE_MIN_LOD: 1864 *params = obj->MinLod; 1865 break; 1866 case GL_TEXTURE_MAX_LOD: 1867 *params = obj->MaxLod; 1868 break; 1869 case GL_TEXTURE_BASE_LEVEL: 1870 *params = (GLfloat) obj->BaseLevel; 1871 break; 1872 case GL_TEXTURE_MAX_LEVEL: 1873 *params = (GLfloat) obj->MaxLevel; 1874 break; 1875 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1876 if (ctx->Extensions.EXT_texture_filter_anisotropic) { 1877 *params = obj->MaxAnisotropy; 1878 } 1879 else 1880 error = 1; 1881 break; 1882 case GL_TEXTURE_COMPARE_SGIX: 1883 if (ctx->Extensions.SGIX_shadow) { 1884 *params = (GLfloat) obj->CompareFlag; 1885 } 1886 else 1887 error = 1; 1888 break; 1889 case GL_TEXTURE_COMPARE_OPERATOR_SGIX: 1890 if (ctx->Extensions.SGIX_shadow) { 1891 *params = (GLfloat) obj->CompareOperator; 1892 } 1893 else 1894 error = 1; 1895 break; 1896 case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */ 1897 if (ctx->Extensions.SGIX_shadow_ambient) { 1898 *params = obj->ShadowAmbient; 1899 } 1900 else 1901 error = 1; 1902 break; 1903 case GL_GENERATE_MIPMAP_SGIS: 1904 if (ctx->Extensions.SGIS_generate_mipmap) { 1905 *params = (GLfloat) obj->GenerateMipmap; 1906 } 1907 else 1908 error = 1; 1909 break; 1910 case GL_TEXTURE_COMPARE_MODE_ARB: 1911 if (ctx->Extensions.ARB_shadow) { 1912 *params = (GLfloat) obj->CompareMode; 1913 } 1914 else 1915 error = 1; 1916 break; 1917 case GL_TEXTURE_COMPARE_FUNC_ARB: 1918 if (ctx->Extensions.ARB_shadow) { 1919 *params = (GLfloat) obj->CompareFunc; 1920 } 1921 else 1922 error = 1; 1923 break; 1924 case GL_DEPTH_TEXTURE_MODE_ARB: 1925 if (ctx->Extensions.ARB_depth_texture) { 1926 *params = (GLfloat) obj->DepthMode; 1927 } 1928 else 1929 error = 1; 1930 break; 1931 case GL_TEXTURE_LOD_BIAS: 1932 if (ctx->Extensions.EXT_texture_lod_bias) { 1933 *params = obj->LodBias; 1934 } 1935 else 1936 error = 1; 1937 break; 1938 default: 1939 error = 1; 1940 break; 1941 } 1942 if (error) 1943 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", 1944 pname); 1945 1946 _mesa_unlock_texture(ctx, obj); 1947} 1948 1949 1950void GLAPIENTRY 1951_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) 1952{ 1953 struct gl_texture_unit *texUnit; 1954 struct gl_texture_object *obj; 1955 GET_CURRENT_CONTEXT(ctx); 1956 ASSERT_OUTSIDE_BEGIN_END(ctx); 1957 1958 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { 1959 _mesa_error(ctx, GL_INVALID_OPERATION, 1960 "glGetTexParameteriv(current unit)"); 1961 return; 1962 } 1963 1964 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1965 1966 obj = _mesa_select_tex_object(ctx, texUnit, target); 1967 if (!obj) { 1968 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)"); 1969 return; 1970 } 1971 1972 switch (pname) { 1973 case GL_TEXTURE_MAG_FILTER: 1974 *params = (GLint) obj->MagFilter; 1975 return; 1976 case GL_TEXTURE_MIN_FILTER: 1977 *params = (GLint) obj->MinFilter; 1978 return; 1979 case GL_TEXTURE_WRAP_S: 1980 *params = (GLint) obj->WrapS; 1981 return; 1982 case GL_TEXTURE_WRAP_T: 1983 *params = (GLint) obj->WrapT; 1984 return; 1985 case GL_TEXTURE_WRAP_R: 1986 *params = (GLint) obj->WrapR; 1987 return; 1988 case GL_TEXTURE_BORDER_COLOR: 1989 { 1990 GLfloat b[4]; 1991 b[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F); 1992 b[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F); 1993 b[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F); 1994 b[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F); 1995 params[0] = FLOAT_TO_INT(b[0]); 1996 params[1] = FLOAT_TO_INT(b[1]); 1997 params[2] = FLOAT_TO_INT(b[2]); 1998 params[3] = FLOAT_TO_INT(b[3]); 1999 } 2000 return; 2001 case GL_TEXTURE_RESIDENT: 2002 { 2003 GLboolean resident; 2004 if (ctx->Driver.IsTextureResident) 2005 resident = ctx->Driver.IsTextureResident(ctx, obj); 2006 else 2007 resident = GL_TRUE; 2008 *params = (GLint) resident; 2009 } 2010 return; 2011 case GL_TEXTURE_PRIORITY: 2012 *params = FLOAT_TO_INT(obj->Priority); 2013 return; 2014 case GL_TEXTURE_MIN_LOD: 2015 *params = (GLint) obj->MinLod; 2016 return; 2017 case GL_TEXTURE_MAX_LOD: 2018 *params = (GLint) obj->MaxLod; 2019 return; 2020 case GL_TEXTURE_BASE_LEVEL: 2021 *params = obj->BaseLevel; 2022 return; 2023 case GL_TEXTURE_MAX_LEVEL: 2024 *params = obj->MaxLevel; 2025 return; 2026 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 2027 if (ctx->Extensions.EXT_texture_filter_anisotropic) { 2028 *params = (GLint) obj->MaxAnisotropy; 2029 return; 2030 } 2031 break; 2032 case GL_TEXTURE_COMPARE_SGIX: 2033 if (ctx->Extensions.SGIX_shadow) { 2034 *params = (GLint) obj->CompareFlag; 2035 return; 2036 } 2037 break; 2038 case GL_TEXTURE_COMPARE_OPERATOR_SGIX: 2039 if (ctx->Extensions.SGIX_shadow) { 2040 *params = (GLint) obj->CompareOperator; 2041 return; 2042 } 2043 break; 2044 case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */ 2045 if (ctx->Extensions.SGIX_shadow_ambient) { 2046 *params = (GLint) FLOAT_TO_INT(obj->ShadowAmbient); 2047 return; 2048 } 2049 break; 2050 case GL_GENERATE_MIPMAP_SGIS: 2051 if (ctx->Extensions.SGIS_generate_mipmap) { 2052 *params = (GLint) obj->GenerateMipmap; 2053 return; 2054 } 2055 break; 2056 case GL_TEXTURE_COMPARE_MODE_ARB: 2057 if (ctx->Extensions.ARB_shadow) { 2058 *params = (GLint) obj->CompareMode; 2059 return; 2060 } 2061 break; 2062 case GL_TEXTURE_COMPARE_FUNC_ARB: 2063 if (ctx->Extensions.ARB_shadow) { 2064 *params = (GLint) obj->CompareFunc; 2065 return; 2066 } 2067 break; 2068 case GL_DEPTH_TEXTURE_MODE_ARB: 2069 if (ctx->Extensions.ARB_depth_texture) { 2070 *params = (GLint) obj->DepthMode; 2071 return; 2072 } 2073 break; 2074 case GL_TEXTURE_LOD_BIAS: 2075 if (ctx->Extensions.EXT_texture_lod_bias) { 2076 *params = (GLint) obj->LodBias; 2077 return; 2078 } 2079 break; 2080 default: 2081 ; /* silence warnings */ 2082 } 2083 /* If we get here, pname was an unrecognized enum */ 2084 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname); 2085} 2086 2087 2088 2089 2090/**********************************************************************/ 2091/* Texture Coord Generation */ 2092/**********************************************************************/ 2093 2094#if FEATURE_texgen 2095void GLAPIENTRY 2096_mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) 2097{ 2098 GET_CURRENT_CONTEXT(ctx); 2099 struct gl_texture_unit *texUnit; 2100 ASSERT_OUTSIDE_BEGIN_END(ctx); 2101 2102 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) 2103 _mesa_debug(ctx, "glTexGen %s %s %.1f(%s)...\n", 2104 _mesa_lookup_enum_by_nr(coord), 2105 _mesa_lookup_enum_by_nr(pname), 2106 *params, 2107 _mesa_lookup_enum_by_nr((GLenum) (GLint) *params)); 2108 2109 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { 2110 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexGen(current unit)"); 2111 return; 2112 } 2113 2114 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2115 2116 switch (coord) { 2117 case GL_S: 2118 if (pname==GL_TEXTURE_GEN_MODE) { 2119 GLenum mode = (GLenum) (GLint) *params; 2120 GLbitfield bits; 2121 switch (mode) { 2122 case GL_OBJECT_LINEAR: 2123 bits = TEXGEN_OBJ_LINEAR; 2124 break; 2125 case GL_EYE_LINEAR: 2126 bits = TEXGEN_EYE_LINEAR; 2127 break; 2128 case GL_REFLECTION_MAP_NV: 2129 bits = TEXGEN_REFLECTION_MAP_NV; 2130 break; 2131 case GL_NORMAL_MAP_NV: 2132 bits = TEXGEN_NORMAL_MAP_NV; 2133 break; 2134 case GL_SPHERE_MAP: 2135 bits = TEXGEN_SPHERE_MAP; 2136 break; 2137 default: 2138 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" ); 2139 return; 2140 } 2141 if (texUnit->GenModeS == mode) 2142 return; 2143 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 2144 texUnit->GenModeS = mode; 2145 texUnit->_GenBitS = bits; 2146 } 2147 else if (pname==GL_OBJECT_PLANE) { 2148 if (TEST_EQ_4V(texUnit->ObjectPlaneS, params)) 2149 return; 2150 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 2151 COPY_4FV(texUnit->ObjectPlaneS, params); 2152 } 2153 else if (pname==GL_EYE_PLANE) { 2154 GLfloat tmp[4]; 2155 /* Transform plane equation by the inverse modelview matrix */ 2156 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) { 2157 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top ); 2158 } 2159 _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv ); 2160 if (TEST_EQ_4V(texUnit->EyePlaneS, tmp)) 2161 return; 2162 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 2163 COPY_4FV(texUnit->EyePlaneS, tmp); 2164 } 2165 else { 2166 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" ); 2167 return; 2168 } 2169 break; 2170 case GL_T: 2171 if (pname==GL_TEXTURE_GEN_MODE) { 2172 GLenum mode = (GLenum) (GLint) *params; 2173 GLbitfield bitt; 2174 switch (mode) { 2175 case GL_OBJECT_LINEAR: 2176 bitt = TEXGEN_OBJ_LINEAR; 2177 break; 2178 case GL_EYE_LINEAR: 2179 bitt = TEXGEN_EYE_LINEAR; 2180 break; 2181 case GL_REFLECTION_MAP_NV: 2182 bitt = TEXGEN_REFLECTION_MAP_NV; 2183 break; 2184 case GL_NORMAL_MAP_NV: 2185 bitt = TEXGEN_NORMAL_MAP_NV; 2186 break; 2187 case GL_SPHERE_MAP: 2188 bitt = TEXGEN_SPHERE_MAP; 2189 break; 2190 default: 2191 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" ); 2192 return; 2193 } 2194 if (texUnit->GenModeT == mode) 2195 return; 2196 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 2197 texUnit->GenModeT = mode; 2198 texUnit->_GenBitT = bitt; 2199 } 2200 else if (pname==GL_OBJECT_PLANE) { 2201 if (TEST_EQ_4V(texUnit->ObjectPlaneT, params)) 2202 return; 2203 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 2204 COPY_4FV(texUnit->ObjectPlaneT, params); 2205 } 2206 else if (pname==GL_EYE_PLANE) { 2207 GLfloat tmp[4]; 2208 /* Transform plane equation by the inverse modelview matrix */ 2209 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) { 2210 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top ); 2211 } 2212 _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv ); 2213 if (TEST_EQ_4V(texUnit->EyePlaneT, tmp)) 2214 return; 2215 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 2216 COPY_4FV(texUnit->EyePlaneT, tmp); 2217 } 2218 else { 2219 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" ); 2220 return; 2221 } 2222 break; 2223 case GL_R: 2224 if (pname==GL_TEXTURE_GEN_MODE) { 2225 GLenum mode = (GLenum) (GLint) *params; 2226 GLbitfield bitr; 2227 switch (mode) { 2228 case GL_OBJECT_LINEAR: 2229 bitr = TEXGEN_OBJ_LINEAR; 2230 break; 2231 case GL_REFLECTION_MAP_NV: 2232 bitr = TEXGEN_REFLECTION_MAP_NV; 2233 break; 2234 case GL_NORMAL_MAP_NV: 2235 bitr = TEXGEN_NORMAL_MAP_NV; 2236 break; 2237 case GL_EYE_LINEAR: 2238 bitr = TEXGEN_EYE_LINEAR; 2239 break; 2240 default: 2241 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" ); 2242 return; 2243 } 2244 if (texUnit->GenModeR == mode) 2245 return; 2246 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 2247 texUnit->GenModeR = mode; 2248 texUnit->_GenBitR = bitr; 2249 } 2250 else if (pname==GL_OBJECT_PLANE) { 2251 if (TEST_EQ_4V(texUnit->ObjectPlaneR, params)) 2252 return; 2253 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 2254 COPY_4FV(texUnit->ObjectPlaneR, params); 2255 } 2256 else if (pname==GL_EYE_PLANE) { 2257 GLfloat tmp[4]; 2258 /* Transform plane equation by the inverse modelview matrix */ 2259 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) { 2260 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top ); 2261 } 2262 _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv ); 2263 if (TEST_EQ_4V(texUnit->EyePlaneR, tmp)) 2264 return; 2265 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 2266 COPY_4FV(texUnit->EyePlaneR, tmp); 2267 } 2268 else { 2269 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" ); 2270 return; 2271 } 2272 break; 2273 case GL_Q: 2274 if (pname==GL_TEXTURE_GEN_MODE) { 2275 GLenum mode = (GLenum) (GLint) *params; 2276 GLbitfield bitq; 2277 switch (mode) { 2278 case GL_OBJECT_LINEAR: 2279 bitq = TEXGEN_OBJ_LINEAR; 2280 break; 2281 case GL_EYE_LINEAR: 2282 bitq = TEXGEN_EYE_LINEAR; 2283 break; 2284 default: 2285 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" ); 2286 return; 2287 } 2288 if (texUnit->GenModeQ == mode) 2289 return; 2290 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 2291 texUnit->GenModeQ = mode; 2292 texUnit->_GenBitQ = bitq; 2293 } 2294 else if (pname==GL_OBJECT_PLANE) { 2295 if (TEST_EQ_4V(texUnit->ObjectPlaneQ, params)) 2296 return; 2297 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 2298 COPY_4FV(texUnit->ObjectPlaneQ, params); 2299 } 2300 else if (pname==GL_EYE_PLANE) { 2301 GLfloat tmp[4]; 2302 /* Transform plane equation by the inverse modelview matrix */ 2303 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) { 2304 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top ); 2305 } 2306 _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv ); 2307 if (TEST_EQ_4V(texUnit->EyePlaneQ, tmp)) 2308 return; 2309 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 2310 COPY_4FV(texUnit->EyePlaneQ, tmp); 2311 } 2312 else { 2313 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" ); 2314 return; 2315 } 2316 break; 2317 default: 2318 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(coord)" ); 2319 return; 2320 } 2321 2322 if (ctx->Driver.TexGen) 2323 ctx->Driver.TexGen( ctx, coord, pname, params ); 2324} 2325 2326 2327void GLAPIENTRY 2328_mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params ) 2329{ 2330 GLfloat p[4]; 2331 p[0] = (GLfloat) params[0]; 2332 if (pname == GL_TEXTURE_GEN_MODE) { 2333 p[1] = p[2] = p[3] = 0.0F; 2334 } 2335 else { 2336 p[1] = (GLfloat) params[1]; 2337 p[2] = (GLfloat) params[2]; 2338 p[3] = (GLfloat) params[3]; 2339 } 2340 _mesa_TexGenfv(coord, pname, p); 2341} 2342 2343 2344void GLAPIENTRY 2345_mesa_TexGend(GLenum coord, GLenum pname, GLdouble param ) 2346{ 2347 GLfloat p = (GLfloat) param; 2348 _mesa_TexGenfv( coord, pname, &p ); 2349} 2350 2351 2352void GLAPIENTRY 2353_mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params ) 2354{ 2355 GLfloat p[4]; 2356 p[0] = (GLfloat) params[0]; 2357 if (pname == GL_TEXTURE_GEN_MODE) { 2358 p[1] = p[2] = p[3] = 0.0F; 2359 } 2360 else { 2361 p[1] = (GLfloat) params[1]; 2362 p[2] = (GLfloat) params[2]; 2363 p[3] = (GLfloat) params[3]; 2364 } 2365 _mesa_TexGenfv( coord, pname, p ); 2366} 2367 2368 2369void GLAPIENTRY 2370_mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param ) 2371{ 2372 _mesa_TexGenfv(coord, pname, ¶m); 2373} 2374 2375 2376void GLAPIENTRY 2377_mesa_TexGeni( GLenum coord, GLenum pname, GLint param ) 2378{ 2379 _mesa_TexGeniv( coord, pname, ¶m ); 2380} 2381 2382 2383 2384void GLAPIENTRY 2385_mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params ) 2386{ 2387 const struct gl_texture_unit *texUnit; 2388 GET_CURRENT_CONTEXT(ctx); 2389 ASSERT_OUTSIDE_BEGIN_END(ctx); 2390 2391 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { 2392 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGendv(current unit)"); 2393 return; 2394 } 2395 2396 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2397 2398 switch (coord) { 2399 case GL_S: 2400 if (pname==GL_TEXTURE_GEN_MODE) { 2401 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeS); 2402 } 2403 else if (pname==GL_OBJECT_PLANE) { 2404 COPY_4V( params, texUnit->ObjectPlaneS ); 2405 } 2406 else if (pname==GL_EYE_PLANE) { 2407 COPY_4V( params, texUnit->EyePlaneS ); 2408 } 2409 else { 2410 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" ); 2411 return; 2412 } 2413 break; 2414 case GL_T: 2415 if (pname==GL_TEXTURE_GEN_MODE) { 2416 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeT); 2417 } 2418 else if (pname==GL_OBJECT_PLANE) { 2419 COPY_4V( params, texUnit->ObjectPlaneT ); 2420 } 2421 else if (pname==GL_EYE_PLANE) { 2422 COPY_4V( params, texUnit->EyePlaneT ); 2423 } 2424 else { 2425 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" ); 2426 return; 2427 } 2428 break; 2429 case GL_R: 2430 if (pname==GL_TEXTURE_GEN_MODE) { 2431 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeR); 2432 } 2433 else if (pname==GL_OBJECT_PLANE) { 2434 COPY_4V( params, texUnit->ObjectPlaneR ); 2435 } 2436 else if (pname==GL_EYE_PLANE) { 2437 COPY_4V( params, texUnit->EyePlaneR ); 2438 } 2439 else { 2440 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" ); 2441 return; 2442 } 2443 break; 2444 case GL_Q: 2445 if (pname==GL_TEXTURE_GEN_MODE) { 2446 params[0] = ENUM_TO_DOUBLE(texUnit->GenModeQ); 2447 } 2448 else if (pname==GL_OBJECT_PLANE) { 2449 COPY_4V( params, texUnit->ObjectPlaneQ ); 2450 } 2451 else if (pname==GL_EYE_PLANE) { 2452 COPY_4V( params, texUnit->EyePlaneQ ); 2453 } 2454 else { 2455 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" ); 2456 return; 2457 } 2458 break; 2459 default: 2460 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)" ); 2461 return; 2462 } 2463} 2464 2465 2466 2467void GLAPIENTRY 2468_mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ) 2469{ 2470 const struct gl_texture_unit *texUnit; 2471 GET_CURRENT_CONTEXT(ctx); 2472 ASSERT_OUTSIDE_BEGIN_END(ctx); 2473 2474 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { 2475 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGenfv(current unit)"); 2476 return; 2477 } 2478 2479 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2480 2481 switch (coord) { 2482 case GL_S: 2483 if (pname==GL_TEXTURE_GEN_MODE) { 2484 params[0] = ENUM_TO_FLOAT(texUnit->GenModeS); 2485 } 2486 else if (pname==GL_OBJECT_PLANE) { 2487 COPY_4V( params, texUnit->ObjectPlaneS ); 2488 } 2489 else if (pname==GL_EYE_PLANE) { 2490 COPY_4V( params, texUnit->EyePlaneS ); 2491 } 2492 else { 2493 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" ); 2494 return; 2495 } 2496 break; 2497 case GL_T: 2498 if (pname==GL_TEXTURE_GEN_MODE) { 2499 params[0] = ENUM_TO_FLOAT(texUnit->GenModeT); 2500 } 2501 else if (pname==GL_OBJECT_PLANE) { 2502 COPY_4V( params, texUnit->ObjectPlaneT ); 2503 } 2504 else if (pname==GL_EYE_PLANE) { 2505 COPY_4V( params, texUnit->EyePlaneT ); 2506 } 2507 else { 2508 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" ); 2509 return; 2510 } 2511 break; 2512 case GL_R: 2513 if (pname==GL_TEXTURE_GEN_MODE) { 2514 params[0] = ENUM_TO_FLOAT(texUnit->GenModeR); 2515 } 2516 else if (pname==GL_OBJECT_PLANE) { 2517 COPY_4V( params, texUnit->ObjectPlaneR ); 2518 } 2519 else if (pname==GL_EYE_PLANE) { 2520 COPY_4V( params, texUnit->EyePlaneR ); 2521 } 2522 else { 2523 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" ); 2524 return; 2525 } 2526 break; 2527 case GL_Q: 2528 if (pname==GL_TEXTURE_GEN_MODE) { 2529 params[0] = ENUM_TO_FLOAT(texUnit->GenModeQ); 2530 } 2531 else if (pname==GL_OBJECT_PLANE) { 2532 COPY_4V( params, texUnit->ObjectPlaneQ ); 2533 } 2534 else if (pname==GL_EYE_PLANE) { 2535 COPY_4V( params, texUnit->EyePlaneQ ); 2536 } 2537 else { 2538 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" ); 2539 return; 2540 } 2541 break; 2542 default: 2543 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)" ); 2544 return; 2545 } 2546} 2547 2548 2549 2550void GLAPIENTRY 2551_mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params ) 2552{ 2553 const struct gl_texture_unit *texUnit; 2554 GET_CURRENT_CONTEXT(ctx); 2555 ASSERT_OUTSIDE_BEGIN_END(ctx); 2556 2557 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { 2558 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGeniv(current unit)"); 2559 return; 2560 } 2561 2562 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2563 2564 switch (coord) { 2565 case GL_S: 2566 if (pname==GL_TEXTURE_GEN_MODE) { 2567 params[0] = texUnit->GenModeS; 2568 } 2569 else if (pname==GL_OBJECT_PLANE) { 2570 params[0] = (GLint) texUnit->ObjectPlaneS[0]; 2571 params[1] = (GLint) texUnit->ObjectPlaneS[1]; 2572 params[2] = (GLint) texUnit->ObjectPlaneS[2]; 2573 params[3] = (GLint) texUnit->ObjectPlaneS[3]; 2574 } 2575 else if (pname==GL_EYE_PLANE) { 2576 params[0] = (GLint) texUnit->EyePlaneS[0]; 2577 params[1] = (GLint) texUnit->EyePlaneS[1]; 2578 params[2] = (GLint) texUnit->EyePlaneS[2]; 2579 params[3] = (GLint) texUnit->EyePlaneS[3]; 2580 } 2581 else { 2582 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" ); 2583 return; 2584 } 2585 break; 2586 case GL_T: 2587 if (pname==GL_TEXTURE_GEN_MODE) { 2588 params[0] = texUnit->GenModeT; 2589 } 2590 else if (pname==GL_OBJECT_PLANE) { 2591 params[0] = (GLint) texUnit->ObjectPlaneT[0]; 2592 params[1] = (GLint) texUnit->ObjectPlaneT[1]; 2593 params[2] = (GLint) texUnit->ObjectPlaneT[2]; 2594 params[3] = (GLint) texUnit->ObjectPlaneT[3]; 2595 } 2596 else if (pname==GL_EYE_PLANE) { 2597 params[0] = (GLint) texUnit->EyePlaneT[0]; 2598 params[1] = (GLint) texUnit->EyePlaneT[1]; 2599 params[2] = (GLint) texUnit->EyePlaneT[2]; 2600 params[3] = (GLint) texUnit->EyePlaneT[3]; 2601 } 2602 else { 2603 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" ); 2604 return; 2605 } 2606 break; 2607 case GL_R: 2608 if (pname==GL_TEXTURE_GEN_MODE) { 2609 params[0] = texUnit->GenModeR; 2610 } 2611 else if (pname==GL_OBJECT_PLANE) { 2612 params[0] = (GLint) texUnit->ObjectPlaneR[0]; 2613 params[1] = (GLint) texUnit->ObjectPlaneR[1]; 2614 params[2] = (GLint) texUnit->ObjectPlaneR[2]; 2615 params[3] = (GLint) texUnit->ObjectPlaneR[3]; 2616 } 2617 else if (pname==GL_EYE_PLANE) { 2618 params[0] = (GLint) texUnit->EyePlaneR[0]; 2619 params[1] = (GLint) texUnit->EyePlaneR[1]; 2620 params[2] = (GLint) texUnit->EyePlaneR[2]; 2621 params[3] = (GLint) texUnit->EyePlaneR[3]; 2622 } 2623 else { 2624 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" ); 2625 return; 2626 } 2627 break; 2628 case GL_Q: 2629 if (pname==GL_TEXTURE_GEN_MODE) { 2630 params[0] = texUnit->GenModeQ; 2631 } 2632 else if (pname==GL_OBJECT_PLANE) { 2633 params[0] = (GLint) texUnit->ObjectPlaneQ[0]; 2634 params[1] = (GLint) texUnit->ObjectPlaneQ[1]; 2635 params[2] = (GLint) texUnit->ObjectPlaneQ[2]; 2636 params[3] = (GLint) texUnit->ObjectPlaneQ[3]; 2637 } 2638 else if (pname==GL_EYE_PLANE) { 2639 params[0] = (GLint) texUnit->EyePlaneQ[0]; 2640 params[1] = (GLint) texUnit->EyePlaneQ[1]; 2641 params[2] = (GLint) texUnit->EyePlaneQ[2]; 2642 params[3] = (GLint) texUnit->EyePlaneQ[3]; 2643 } 2644 else { 2645 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" ); 2646 return; 2647 } 2648 break; 2649 default: 2650 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)" ); 2651 return; 2652 } 2653} 2654#endif 2655 2656 2657/* GL_ARB_multitexture */ 2658void GLAPIENTRY 2659_mesa_ActiveTextureARB(GLenum texture) 2660{ 2661 GET_CURRENT_CONTEXT(ctx); 2662 const GLuint texUnit = texture - GL_TEXTURE0; 2663 ASSERT_OUTSIDE_BEGIN_END(ctx); 2664 2665 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2666 _mesa_debug(ctx, "glActiveTexture %s\n", 2667 _mesa_lookup_enum_by_nr(texture)); 2668 2669 /* XXX error-check against max(coordunits, imageunits) */ 2670 if (texUnit >= ctx->Const.MaxTextureUnits) { 2671 _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture)"); 2672 return; 2673 } 2674 2675 if (ctx->Texture.CurrentUnit == texUnit) 2676 return; 2677 2678 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 2679 2680 ctx->Texture.CurrentUnit = texUnit; 2681 if (ctx->Transform.MatrixMode == GL_TEXTURE) { 2682 /* update current stack pointer */ 2683 ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit]; 2684 } 2685 2686 if (ctx->Driver.ActiveTexture) { 2687 (*ctx->Driver.ActiveTexture)( ctx, (GLuint) texUnit ); 2688 } 2689} 2690 2691 2692/* GL_ARB_multitexture */ 2693void GLAPIENTRY 2694_mesa_ClientActiveTextureARB(GLenum texture) 2695{ 2696 GET_CURRENT_CONTEXT(ctx); 2697 GLuint texUnit = texture - GL_TEXTURE0; 2698 ASSERT_OUTSIDE_BEGIN_END(ctx); 2699 2700 if (texUnit >= ctx->Const.MaxTextureCoordUnits) { 2701 _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(texture)"); 2702 return; 2703 } 2704 2705 FLUSH_VERTICES(ctx, _NEW_ARRAY); 2706 ctx->Array.ActiveTexture = texUnit; 2707} 2708 2709 2710 2711/**********************************************************************/ 2712/***** State management *****/ 2713/**********************************************************************/ 2714 2715 2716/** 2717 * \note This routine refers to derived texture attribute values to 2718 * compute the ENABLE_TEXMAT flags, but is only called on 2719 * _NEW_TEXTURE_MATRIX. On changes to _NEW_TEXTURE, the ENABLE_TEXMAT 2720 * flags are updated by _mesa_update_textures(), below. 2721 * 2722 * \param ctx GL context. 2723 */ 2724static void 2725update_texture_matrices( GLcontext *ctx ) 2726{ 2727 GLuint i; 2728 2729 ctx->Texture._TexMatEnabled = 0; 2730 2731 for (i=0; i < ctx->Const.MaxTextureUnits; i++) { 2732 if (_math_matrix_is_dirty(ctx->TextureMatrixStack[i].Top)) { 2733 _math_matrix_analyse( ctx->TextureMatrixStack[i].Top ); 2734 2735 if (ctx->Texture.Unit[i]._ReallyEnabled && 2736 ctx->TextureMatrixStack[i].Top->type != MATRIX_IDENTITY) 2737 ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(i); 2738 2739 if (ctx->Driver.TextureMatrix) 2740 ctx->Driver.TextureMatrix( ctx, i, ctx->TextureMatrixStack[i].Top); 2741 } 2742 } 2743} 2744 2745 2746/** 2747 * Helper function for determining which texture object (1D, 2D, cube, etc) 2748 * should actually be used. 2749 */ 2750static void 2751texture_override(GLcontext *ctx, 2752 struct gl_texture_unit *texUnit, GLbitfield enableBits, 2753 struct gl_texture_object *texObj, GLuint textureBit) 2754{ 2755 if (!texUnit->_ReallyEnabled && (enableBits & textureBit)) { 2756 if (!texObj->Complete) { 2757 _mesa_test_texobj_completeness(ctx, texObj); 2758 } 2759 if (texObj->Complete) { 2760 texUnit->_ReallyEnabled = textureBit; 2761 texUnit->_Current = texObj; 2762 } 2763 } 2764} 2765 2766 2767/** 2768 * \note This routine refers to derived texture matrix values to 2769 * compute the ENABLE_TEXMAT flags, but is only called on 2770 * _NEW_TEXTURE. On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT 2771 * flags are updated by _mesa_update_texture_matrices, above. 2772 * 2773 * \param ctx GL context. 2774 */ 2775static void 2776update_texture_state( GLcontext *ctx ) 2777{ 2778 GLuint unit; 2779 struct gl_fragment_program *fprog = NULL; 2780 struct gl_vertex_program *vprog = NULL; 2781 2782 if (ctx->Shader.CurrentProgram && 2783 ctx->Shader.CurrentProgram->LinkStatus) { 2784 fprog = ctx->Shader.CurrentProgram->FragmentProgram; 2785 vprog = ctx->Shader.CurrentProgram->VertexProgram; 2786 } 2787 else { 2788 if (ctx->FragmentProgram._Enabled) { 2789 fprog = ctx->FragmentProgram.Current; 2790 } 2791 if (ctx->VertexProgram._Enabled) { 2792 /* XXX enable this if/when non-shader vertex programs get 2793 * texture fetches: 2794 vprog = ctx->VertexProgram.Current; 2795 */ 2796 } 2797 } 2798 2799 ctx->NewState |= _NEW_TEXTURE; /* TODO: only set this if there are 2800 * actual changes. 2801 */ 2802 2803 ctx->Texture._EnabledUnits = 0; 2804 ctx->Texture._GenFlags = 0; 2805 ctx->Texture._TexMatEnabled = 0; 2806 ctx->Texture._TexGenEnabled = 0; 2807 2808 /* 2809 * Update texture unit state. 2810 */ 2811 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { 2812 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 2813 GLbitfield enableBits; 2814 2815 texUnit->_Current = NULL; 2816 texUnit->_ReallyEnabled = 0; 2817 texUnit->_GenFlags = 0; 2818 2819 /* Get the bitmask of texture enables. 2820 * enableBits will be a mask of the TEXTURE_*_BIT flags indicating 2821 * which texture targets are enabled (fixed function) or referenced 2822 * by a fragment shader/program. When multiple flags are set, we'll 2823 * settle on the one with highest priority (see texture_override below). 2824 */ 2825 if (fprog || vprog) { 2826 enableBits = 0x0; 2827 if (fprog) 2828 enableBits |= fprog->Base.TexturesUsed[unit]; 2829 if (vprog) 2830 enableBits |= vprog->Base.TexturesUsed[unit]; 2831 } 2832 else { 2833 if (!texUnit->Enabled) 2834 continue; 2835 enableBits = texUnit->Enabled; 2836 } 2837 2838 /* Look for the highest-priority texture target that's enabled and 2839 * complete. That's the one we'll use for texturing. If we're using 2840 * a fragment program we're guaranteed that bitcount(enabledBits) <= 1. 2841 */ 2842 texture_override(ctx, texUnit, enableBits, 2843 texUnit->CurrentCubeMap, TEXTURE_CUBE_BIT); 2844 texture_override(ctx, texUnit, enableBits, 2845 texUnit->Current3D, TEXTURE_3D_BIT); 2846 texture_override(ctx, texUnit, enableBits, 2847 texUnit->CurrentRect, TEXTURE_RECT_BIT); 2848 texture_override(ctx, texUnit, enableBits, 2849 texUnit->Current2D, TEXTURE_2D_BIT); 2850 texture_override(ctx, texUnit, enableBits, 2851 texUnit->Current1D, TEXTURE_1D_BIT); 2852 2853 if (!texUnit->_ReallyEnabled) { 2854 continue; 2855 } 2856 2857 if (texUnit->_ReallyEnabled) 2858 ctx->Texture._EnabledUnits |= (1 << unit); 2859 2860 if (texUnit->EnvMode == GL_COMBINE) { 2861 texUnit->_CurrentCombine = & texUnit->Combine; 2862 } 2863 else { 2864 const struct gl_texture_object *texObj = texUnit->_Current; 2865 GLenum format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat; 2866 if (format == GL_COLOR_INDEX) { 2867 format = GL_RGBA; /* a bit of a hack */ 2868 } 2869 else if (format == GL_DEPTH_COMPONENT 2870 || format == GL_DEPTH_STENCIL_EXT) { 2871 format = texObj->DepthMode; 2872 } 2873 calculate_derived_texenv(&texUnit->_EnvMode, texUnit->EnvMode, format); 2874 texUnit->_CurrentCombine = & texUnit->_EnvMode; 2875 } 2876 2877 switch (texUnit->_CurrentCombine->ModeRGB) { 2878 case GL_REPLACE: 2879 texUnit->_CurrentCombine->_NumArgsRGB = 1; 2880 break; 2881 case GL_MODULATE: 2882 case GL_ADD: 2883 case GL_ADD_SIGNED: 2884 case GL_SUBTRACT: 2885 case GL_DOT3_RGB: 2886 case GL_DOT3_RGBA: 2887 case GL_DOT3_RGB_EXT: 2888 case GL_DOT3_RGBA_EXT: 2889 texUnit->_CurrentCombine->_NumArgsRGB = 2; 2890 break; 2891 case GL_INTERPOLATE: 2892 case GL_MODULATE_ADD_ATI: 2893 case GL_MODULATE_SIGNED_ADD_ATI: 2894 case GL_MODULATE_SUBTRACT_ATI: 2895 texUnit->_CurrentCombine->_NumArgsRGB = 3; 2896 break; 2897 default: 2898 texUnit->_CurrentCombine->_NumArgsRGB = 0; 2899 _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state"); 2900 return; 2901 } 2902 2903 switch (texUnit->_CurrentCombine->ModeA) { 2904 case GL_REPLACE: 2905 texUnit->_CurrentCombine->_NumArgsA = 1; 2906 break; 2907 case GL_MODULATE: 2908 case GL_ADD: 2909 case GL_ADD_SIGNED: 2910 case GL_SUBTRACT: 2911 texUnit->_CurrentCombine->_NumArgsA = 2; 2912 break; 2913 case GL_INTERPOLATE: 2914 case GL_MODULATE_ADD_ATI: 2915 case GL_MODULATE_SIGNED_ADD_ATI: 2916 case GL_MODULATE_SUBTRACT_ATI: 2917 texUnit->_CurrentCombine->_NumArgsA = 3; 2918 break; 2919 default: 2920 texUnit->_CurrentCombine->_NumArgsA = 0; 2921 _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state"); 2922 break; 2923 } 2924 2925 if (texUnit->TexGenEnabled) { 2926 if (texUnit->TexGenEnabled & S_BIT) { 2927 texUnit->_GenFlags |= texUnit->_GenBitS; 2928 } 2929 if (texUnit->TexGenEnabled & T_BIT) { 2930 texUnit->_GenFlags |= texUnit->_GenBitT; 2931 } 2932 if (texUnit->TexGenEnabled & Q_BIT) { 2933 texUnit->_GenFlags |= texUnit->_GenBitQ; 2934 } 2935 if (texUnit->TexGenEnabled & R_BIT) { 2936 texUnit->_GenFlags |= texUnit->_GenBitR; 2937 } 2938 2939 ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit); 2940 ctx->Texture._GenFlags |= texUnit->_GenFlags; 2941 } 2942 2943 if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) 2944 ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit); 2945 } 2946 2947 /* Determine which texture coordinate sets are actually needed */ 2948 if (fprog) { 2949 const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1; 2950 ctx->Texture._EnabledCoordUnits 2951 = (fprog->Base.InputsRead >> FRAG_ATTRIB_TEX0) & coordMask; 2952 } 2953 else { 2954 ctx->Texture._EnabledCoordUnits = ctx->Texture._EnabledUnits; 2955 } 2956} 2957 2958 2959/** 2960 * Update texture-related derived state. 2961 */ 2962void 2963_mesa_update_texture( GLcontext *ctx, GLuint new_state ) 2964{ 2965 if (new_state & _NEW_TEXTURE_MATRIX) 2966 update_texture_matrices( ctx ); 2967 2968 if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM)) 2969 update_texture_state( ctx ); 2970} 2971 2972 2973/**********************************************************************/ 2974/***** Initialization *****/ 2975/**********************************************************************/ 2976 2977/** 2978 * Allocate the proxy textures for the given context. 2979 * 2980 * \param ctx the context to allocate proxies for. 2981 * 2982 * \return GL_TRUE on success, or GL_FALSE on failure 2983 * 2984 * If run out of memory part way through the allocations, clean up and return 2985 * GL_FALSE. 2986 */ 2987static GLboolean 2988alloc_proxy_textures( GLcontext *ctx ) 2989{ 2990 ctx->Texture.Proxy1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D); 2991 if (!ctx->Texture.Proxy1D) 2992 goto cleanup; 2993 2994 ctx->Texture.Proxy2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D); 2995 if (!ctx->Texture.Proxy2D) 2996 goto cleanup; 2997 2998 ctx->Texture.Proxy3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D); 2999 if (!ctx->Texture.Proxy3D) 3000 goto cleanup; 3001 3002 ctx->Texture.ProxyCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB); 3003 if (!ctx->Texture.ProxyCubeMap) 3004 goto cleanup; 3005 3006 ctx->Texture.ProxyRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV); 3007 if (!ctx->Texture.ProxyRect) 3008 goto cleanup; 3009 3010 assert(ctx->Texture.Proxy1D->RefCount == 1); 3011 3012 return GL_TRUE; 3013 3014 cleanup: 3015 if (ctx->Texture.Proxy1D) 3016 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D); 3017 if (ctx->Texture.Proxy2D) 3018 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D); 3019 if (ctx->Texture.Proxy3D) 3020 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D); 3021 if (ctx->Texture.ProxyCubeMap) 3022 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap); 3023 if (ctx->Texture.ProxyRect) 3024 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect); 3025 return GL_FALSE; 3026} 3027 3028 3029/** 3030 * Initialize a texture unit. 3031 * 3032 * \param ctx GL context. 3033 * \param unit texture unit number to be initialized. 3034 */ 3035static void 3036init_texture_unit( GLcontext *ctx, GLuint unit ) 3037{ 3038 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 3039 3040 texUnit->EnvMode = GL_MODULATE; 3041 ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 ); 3042 3043 texUnit->Combine = default_combine_state; 3044 texUnit->_EnvMode = default_combine_state; 3045 texUnit->_CurrentCombine = & texUnit->_EnvMode; 3046 3047 texUnit->TexGenEnabled = 0; 3048 texUnit->GenModeS = GL_EYE_LINEAR; 3049 texUnit->GenModeT = GL_EYE_LINEAR; 3050 texUnit->GenModeR = GL_EYE_LINEAR; 3051 texUnit->GenModeQ = GL_EYE_LINEAR; 3052 texUnit->_GenBitS = TEXGEN_EYE_LINEAR; 3053 texUnit->_GenBitT = TEXGEN_EYE_LINEAR; 3054 texUnit->_GenBitR = TEXGEN_EYE_LINEAR; 3055 texUnit->_GenBitQ = TEXGEN_EYE_LINEAR; 3056 3057 /* Yes, these plane coefficients are correct! */ 3058 ASSIGN_4V( texUnit->ObjectPlaneS, 1.0, 0.0, 0.0, 0.0 ); 3059 ASSIGN_4V( texUnit->ObjectPlaneT, 0.0, 1.0, 0.0, 0.0 ); 3060 ASSIGN_4V( texUnit->ObjectPlaneR, 0.0, 0.0, 0.0, 0.0 ); 3061 ASSIGN_4V( texUnit->ObjectPlaneQ, 0.0, 0.0, 0.0, 0.0 ); 3062 ASSIGN_4V( texUnit->EyePlaneS, 1.0, 0.0, 0.0, 0.0 ); 3063 ASSIGN_4V( texUnit->EyePlaneT, 0.0, 1.0, 0.0, 0.0 ); 3064 ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 ); 3065 ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 ); 3066 3067 /* initialize current texture object ptrs to the shared default objects */ 3068 _mesa_reference_texobj(&texUnit->Current1D, ctx->Shared->Default1D); 3069 _mesa_reference_texobj(&texUnit->Current2D, ctx->Shared->Default2D); 3070 _mesa_reference_texobj(&texUnit->Current3D, ctx->Shared->Default3D); 3071 _mesa_reference_texobj(&texUnit->CurrentCubeMap, ctx->Shared->DefaultCubeMap); 3072 _mesa_reference_texobj(&texUnit->CurrentRect, ctx->Shared->DefaultRect); 3073} 3074 3075 3076/** 3077 * Initialize texture state for the given context. 3078 */ 3079GLboolean 3080_mesa_init_texture(GLcontext *ctx) 3081{ 3082 GLuint i; 3083 3084 assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS); 3085 assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS); 3086 3087 /* Texture group */ 3088 ctx->Texture.CurrentUnit = 0; /* multitexture */ 3089 ctx->Texture._EnabledUnits = 0; 3090 ctx->Texture.SharedPalette = GL_FALSE; 3091 _mesa_init_colortable(&ctx->Texture.Palette); 3092 3093 for (i = 0; i < MAX_TEXTURE_UNITS; i++) 3094 init_texture_unit( ctx, i ); 3095 3096 /* After we're done initializing the context's texture state the default 3097 * texture objects' refcounts should be at least MAX_TEXTURE_UNITS + 1. 3098 */ 3099 assert(ctx->Shared->Default1D->RefCount >= MAX_TEXTURE_UNITS + 1); 3100 3101 _mesa_TexEnvProgramCacheInit( ctx ); 3102 3103 /* Allocate proxy textures */ 3104 if (!alloc_proxy_textures( ctx )) 3105 return GL_FALSE; 3106 3107 return GL_TRUE; 3108} 3109 3110 3111/** 3112 * Free dynamically-allocated texture data attached to the given context. 3113 */ 3114void 3115_mesa_free_texture_data(GLcontext *ctx) 3116{ 3117 GLuint u; 3118 3119 /* unreference current textures */ 3120 for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) { 3121 struct gl_texture_unit *unit = ctx->Texture.Unit + u; 3122 _mesa_reference_texobj(&unit->Current1D, NULL); 3123 _mesa_reference_texobj(&unit->Current2D, NULL); 3124 _mesa_reference_texobj(&unit->Current3D, NULL); 3125 _mesa_reference_texobj(&unit->CurrentCubeMap, NULL); 3126 _mesa_reference_texobj(&unit->CurrentRect, NULL); 3127 } 3128 3129 /* Free proxy texture objects */ 3130 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D ); 3131 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D ); 3132 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D ); 3133 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap ); 3134 (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect ); 3135 3136 for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) 3137 _mesa_free_colortable_data( &ctx->Texture.Unit[u].ColorTable ); 3138 3139 _mesa_TexEnvProgramCacheDestroy( ctx ); 3140} 3141