1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Mesa 3-D graphics library 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5bf215546Sopenharmony_ci * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6bf215546Sopenharmony_ci * 7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 9bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 10bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 12bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 15bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 16bf215546Sopenharmony_ci * 17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 24bf215546Sopenharmony_ci */ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci/** 27bf215546Sopenharmony_ci * \file texenv.c 28bf215546Sopenharmony_ci * 29bf215546Sopenharmony_ci * glTexEnv-related functions 30bf215546Sopenharmony_ci */ 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci#include "main/glheader.h" 34bf215546Sopenharmony_ci#include "main/context.h" 35bf215546Sopenharmony_ci#include "main/blend.h" 36bf215546Sopenharmony_ci#include "main/enums.h" 37bf215546Sopenharmony_ci#include "main/macros.h" 38bf215546Sopenharmony_ci#include "main/mtypes.h" 39bf215546Sopenharmony_ci#include "main/state.h" 40bf215546Sopenharmony_ci#include "main/texstate.h" 41bf215546Sopenharmony_ci#include "api_exec_decl.h" 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci#define TE_ERROR(errCode, msg, value) \ 45bf215546Sopenharmony_ci _mesa_error(ctx, errCode, msg, _mesa_enum_to_string(value)); 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci/** Set texture env mode */ 49bf215546Sopenharmony_cistatic void 50bf215546Sopenharmony_ciset_env_mode(struct gl_context *ctx, 51bf215546Sopenharmony_ci struct gl_fixedfunc_texture_unit *texUnit, 52bf215546Sopenharmony_ci GLenum mode) 53bf215546Sopenharmony_ci{ 54bf215546Sopenharmony_ci GLboolean legal; 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci if (texUnit->EnvMode == mode) 57bf215546Sopenharmony_ci return; 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci switch (mode) { 60bf215546Sopenharmony_ci case GL_MODULATE: 61bf215546Sopenharmony_ci case GL_BLEND: 62bf215546Sopenharmony_ci case GL_DECAL: 63bf215546Sopenharmony_ci case GL_REPLACE: 64bf215546Sopenharmony_ci case GL_ADD: 65bf215546Sopenharmony_ci case GL_COMBINE: 66bf215546Sopenharmony_ci legal = GL_TRUE; 67bf215546Sopenharmony_ci break; 68bf215546Sopenharmony_ci case GL_REPLACE_EXT: 69bf215546Sopenharmony_ci mode = GL_REPLACE; /* GL_REPLACE_EXT != GL_REPLACE */ 70bf215546Sopenharmony_ci legal = GL_TRUE; 71bf215546Sopenharmony_ci break; 72bf215546Sopenharmony_ci case GL_COMBINE4_NV: 73bf215546Sopenharmony_ci legal = ctx->Extensions.NV_texture_env_combine4; 74bf215546Sopenharmony_ci break; 75bf215546Sopenharmony_ci default: 76bf215546Sopenharmony_ci legal = GL_FALSE; 77bf215546Sopenharmony_ci } 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci if (legal) { 80bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT); 81bf215546Sopenharmony_ci texUnit->EnvMode = mode; 82bf215546Sopenharmony_ci } 83bf215546Sopenharmony_ci else { 84bf215546Sopenharmony_ci TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); 85bf215546Sopenharmony_ci } 86bf215546Sopenharmony_ci} 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_cistatic void 90bf215546Sopenharmony_ciset_env_color(struct gl_context *ctx, 91bf215546Sopenharmony_ci struct gl_fixedfunc_texture_unit *texUnit, 92bf215546Sopenharmony_ci const GLfloat *color) 93bf215546Sopenharmony_ci{ 94bf215546Sopenharmony_ci if (TEST_EQ_4V(color, texUnit->EnvColorUnclamped)) 95bf215546Sopenharmony_ci return; 96bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT); 97bf215546Sopenharmony_ci COPY_4FV(texUnit->EnvColorUnclamped, color); 98bf215546Sopenharmony_ci texUnit->EnvColor[0] = CLAMP(color[0], 0.0F, 1.0F); 99bf215546Sopenharmony_ci texUnit->EnvColor[1] = CLAMP(color[1], 0.0F, 1.0F); 100bf215546Sopenharmony_ci texUnit->EnvColor[2] = CLAMP(color[2], 0.0F, 1.0F); 101bf215546Sopenharmony_ci texUnit->EnvColor[3] = CLAMP(color[3], 0.0F, 1.0F); 102bf215546Sopenharmony_ci} 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci/** Set an RGB or A combiner mode/function */ 106bf215546Sopenharmony_cistatic bool 107bf215546Sopenharmony_ciset_combiner_mode(struct gl_context *ctx, 108bf215546Sopenharmony_ci struct gl_fixedfunc_texture_unit *texUnit, 109bf215546Sopenharmony_ci GLenum pname, GLenum mode) 110bf215546Sopenharmony_ci{ 111bf215546Sopenharmony_ci GLboolean legal; 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci switch (mode) { 114bf215546Sopenharmony_ci case GL_REPLACE: 115bf215546Sopenharmony_ci case GL_MODULATE: 116bf215546Sopenharmony_ci case GL_ADD: 117bf215546Sopenharmony_ci case GL_ADD_SIGNED: 118bf215546Sopenharmony_ci case GL_INTERPOLATE: 119bf215546Sopenharmony_ci case GL_SUBTRACT: 120bf215546Sopenharmony_ci legal = GL_TRUE; 121bf215546Sopenharmony_ci break; 122bf215546Sopenharmony_ci case GL_DOT3_RGB_EXT: 123bf215546Sopenharmony_ci case GL_DOT3_RGBA_EXT: 124bf215546Sopenharmony_ci legal = (ctx->API == API_OPENGL_COMPAT && 125bf215546Sopenharmony_ci ctx->Extensions.EXT_texture_env_dot3 && 126bf215546Sopenharmony_ci pname == GL_COMBINE_RGB); 127bf215546Sopenharmony_ci break; 128bf215546Sopenharmony_ci case GL_DOT3_RGB: 129bf215546Sopenharmony_ci case GL_DOT3_RGBA: 130bf215546Sopenharmony_ci legal = (pname == GL_COMBINE_RGB); 131bf215546Sopenharmony_ci break; 132bf215546Sopenharmony_ci case GL_MODULATE_ADD_ATI: 133bf215546Sopenharmony_ci case GL_MODULATE_SIGNED_ADD_ATI: 134bf215546Sopenharmony_ci case GL_MODULATE_SUBTRACT_ATI: 135bf215546Sopenharmony_ci legal = (ctx->API == API_OPENGL_COMPAT && 136bf215546Sopenharmony_ci ctx->Extensions.ATI_texture_env_combine3); 137bf215546Sopenharmony_ci break; 138bf215546Sopenharmony_ci default: 139bf215546Sopenharmony_ci legal = GL_FALSE; 140bf215546Sopenharmony_ci } 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci if (!legal) { 143bf215546Sopenharmony_ci TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); 144bf215546Sopenharmony_ci return false; 145bf215546Sopenharmony_ci } 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci switch (pname) { 148bf215546Sopenharmony_ci case GL_COMBINE_RGB: 149bf215546Sopenharmony_ci if (texUnit->Combine.ModeRGB == mode) 150bf215546Sopenharmony_ci return true; 151bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT); 152bf215546Sopenharmony_ci texUnit->Combine.ModeRGB = mode; 153bf215546Sopenharmony_ci break; 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci case GL_COMBINE_ALPHA: 156bf215546Sopenharmony_ci if (texUnit->Combine.ModeA == mode) 157bf215546Sopenharmony_ci return true; 158bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT); 159bf215546Sopenharmony_ci texUnit->Combine.ModeA = mode; 160bf215546Sopenharmony_ci break; 161bf215546Sopenharmony_ci default: 162bf215546Sopenharmony_ci TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 163bf215546Sopenharmony_ci return false; 164bf215546Sopenharmony_ci } 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci return true; 167bf215546Sopenharmony_ci} 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci/** Set an RGB or A combiner source term */ 172bf215546Sopenharmony_cistatic bool 173bf215546Sopenharmony_ciset_combiner_source(struct gl_context *ctx, 174bf215546Sopenharmony_ci struct gl_fixedfunc_texture_unit *texUnit, 175bf215546Sopenharmony_ci GLenum pname, GLenum param) 176bf215546Sopenharmony_ci{ 177bf215546Sopenharmony_ci GLuint term; 178bf215546Sopenharmony_ci GLboolean alpha, legal; 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci /* 181bf215546Sopenharmony_ci * Translate pname to (term, alpha). 182bf215546Sopenharmony_ci * 183bf215546Sopenharmony_ci * The enums were given sequential values for a reason. 184bf215546Sopenharmony_ci */ 185bf215546Sopenharmony_ci switch (pname) { 186bf215546Sopenharmony_ci case GL_SOURCE0_RGB: 187bf215546Sopenharmony_ci case GL_SOURCE1_RGB: 188bf215546Sopenharmony_ci case GL_SOURCE2_RGB: 189bf215546Sopenharmony_ci case GL_SOURCE3_RGB_NV: 190bf215546Sopenharmony_ci term = pname - GL_SOURCE0_RGB; 191bf215546Sopenharmony_ci alpha = GL_FALSE; 192bf215546Sopenharmony_ci break; 193bf215546Sopenharmony_ci case GL_SOURCE0_ALPHA: 194bf215546Sopenharmony_ci case GL_SOURCE1_ALPHA: 195bf215546Sopenharmony_ci case GL_SOURCE2_ALPHA: 196bf215546Sopenharmony_ci case GL_SOURCE3_ALPHA_NV: 197bf215546Sopenharmony_ci term = pname - GL_SOURCE0_ALPHA; 198bf215546Sopenharmony_ci alpha = GL_TRUE; 199bf215546Sopenharmony_ci break; 200bf215546Sopenharmony_ci default: 201bf215546Sopenharmony_ci TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 202bf215546Sopenharmony_ci return false; 203bf215546Sopenharmony_ci } 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci if ((term == 3) && (ctx->API != API_OPENGL_COMPAT 206bf215546Sopenharmony_ci || !ctx->Extensions.NV_texture_env_combine4)) { 207bf215546Sopenharmony_ci TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 208bf215546Sopenharmony_ci return false; 209bf215546Sopenharmony_ci } 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci assert(term < MAX_COMBINER_TERMS); 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci /* 214bf215546Sopenharmony_ci * Error-check param (the source term) 215bf215546Sopenharmony_ci */ 216bf215546Sopenharmony_ci switch (param) { 217bf215546Sopenharmony_ci case GL_TEXTURE: 218bf215546Sopenharmony_ci case GL_CONSTANT: 219bf215546Sopenharmony_ci case GL_PRIMARY_COLOR: 220bf215546Sopenharmony_ci case GL_PREVIOUS: 221bf215546Sopenharmony_ci legal = GL_TRUE; 222bf215546Sopenharmony_ci break; 223bf215546Sopenharmony_ci case GL_TEXTURE0: 224bf215546Sopenharmony_ci case GL_TEXTURE1: 225bf215546Sopenharmony_ci case GL_TEXTURE2: 226bf215546Sopenharmony_ci case GL_TEXTURE3: 227bf215546Sopenharmony_ci case GL_TEXTURE4: 228bf215546Sopenharmony_ci case GL_TEXTURE5: 229bf215546Sopenharmony_ci case GL_TEXTURE6: 230bf215546Sopenharmony_ci case GL_TEXTURE7: 231bf215546Sopenharmony_ci legal = (param - GL_TEXTURE0 < ctx->Const.MaxTextureUnits); 232bf215546Sopenharmony_ci break; 233bf215546Sopenharmony_ci case GL_ZERO: 234bf215546Sopenharmony_ci legal = (ctx->API == API_OPENGL_COMPAT && 235bf215546Sopenharmony_ci (ctx->Extensions.ATI_texture_env_combine3 || 236bf215546Sopenharmony_ci ctx->Extensions.NV_texture_env_combine4)); 237bf215546Sopenharmony_ci break; 238bf215546Sopenharmony_ci case GL_ONE: 239bf215546Sopenharmony_ci legal = (ctx->API == API_OPENGL_COMPAT && 240bf215546Sopenharmony_ci ctx->Extensions.ATI_texture_env_combine3); 241bf215546Sopenharmony_ci break; 242bf215546Sopenharmony_ci default: 243bf215546Sopenharmony_ci legal = GL_FALSE; 244bf215546Sopenharmony_ci } 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci if (!legal) { 247bf215546Sopenharmony_ci TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", param); 248bf215546Sopenharmony_ci return false; 249bf215546Sopenharmony_ci } 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT); 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci if (alpha) 254bf215546Sopenharmony_ci texUnit->Combine.SourceA[term] = param; 255bf215546Sopenharmony_ci else 256bf215546Sopenharmony_ci texUnit->Combine.SourceRGB[term] = param; 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci return true; 259bf215546Sopenharmony_ci} 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_ci/** Set an RGB or A combiner operand term */ 263bf215546Sopenharmony_cistatic bool 264bf215546Sopenharmony_ciset_combiner_operand(struct gl_context *ctx, 265bf215546Sopenharmony_ci struct gl_fixedfunc_texture_unit *texUnit, 266bf215546Sopenharmony_ci GLenum pname, GLenum param) 267bf215546Sopenharmony_ci{ 268bf215546Sopenharmony_ci GLuint term; 269bf215546Sopenharmony_ci GLboolean alpha, legal; 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci /* The enums were given sequential values for a reason. 272bf215546Sopenharmony_ci */ 273bf215546Sopenharmony_ci switch (pname) { 274bf215546Sopenharmony_ci case GL_OPERAND0_RGB: 275bf215546Sopenharmony_ci case GL_OPERAND1_RGB: 276bf215546Sopenharmony_ci case GL_OPERAND2_RGB: 277bf215546Sopenharmony_ci case GL_OPERAND3_RGB_NV: 278bf215546Sopenharmony_ci term = pname - GL_OPERAND0_RGB; 279bf215546Sopenharmony_ci alpha = GL_FALSE; 280bf215546Sopenharmony_ci break; 281bf215546Sopenharmony_ci case GL_OPERAND0_ALPHA: 282bf215546Sopenharmony_ci case GL_OPERAND1_ALPHA: 283bf215546Sopenharmony_ci case GL_OPERAND2_ALPHA: 284bf215546Sopenharmony_ci case GL_OPERAND3_ALPHA_NV: 285bf215546Sopenharmony_ci term = pname - GL_OPERAND0_ALPHA; 286bf215546Sopenharmony_ci alpha = GL_TRUE; 287bf215546Sopenharmony_ci break; 288bf215546Sopenharmony_ci default: 289bf215546Sopenharmony_ci TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 290bf215546Sopenharmony_ci return false; 291bf215546Sopenharmony_ci } 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci if ((term == 3) && (ctx->API != API_OPENGL_COMPAT 294bf215546Sopenharmony_ci || !ctx->Extensions.NV_texture_env_combine4)) { 295bf215546Sopenharmony_ci TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 296bf215546Sopenharmony_ci return false; 297bf215546Sopenharmony_ci } 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci assert(term < MAX_COMBINER_TERMS); 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci /* 302bf215546Sopenharmony_ci * Error-check param (the source operand) 303bf215546Sopenharmony_ci */ 304bf215546Sopenharmony_ci switch (param) { 305bf215546Sopenharmony_ci case GL_SRC_COLOR: 306bf215546Sopenharmony_ci case GL_ONE_MINUS_SRC_COLOR: 307bf215546Sopenharmony_ci legal = !alpha; 308bf215546Sopenharmony_ci break; 309bf215546Sopenharmony_ci case GL_ONE_MINUS_SRC_ALPHA: 310bf215546Sopenharmony_ci case GL_SRC_ALPHA: 311bf215546Sopenharmony_ci legal = GL_TRUE; 312bf215546Sopenharmony_ci break; 313bf215546Sopenharmony_ci default: 314bf215546Sopenharmony_ci legal = GL_FALSE; 315bf215546Sopenharmony_ci } 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci if (!legal) { 318bf215546Sopenharmony_ci TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", param); 319bf215546Sopenharmony_ci return false; 320bf215546Sopenharmony_ci } 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT); 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci if (alpha) 325bf215546Sopenharmony_ci texUnit->Combine.OperandA[term] = param; 326bf215546Sopenharmony_ci else 327bf215546Sopenharmony_ci texUnit->Combine.OperandRGB[term] = param; 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci return true; 330bf215546Sopenharmony_ci} 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_cistatic bool 334bf215546Sopenharmony_ciset_combiner_scale(struct gl_context *ctx, 335bf215546Sopenharmony_ci struct gl_fixedfunc_texture_unit *texUnit, 336bf215546Sopenharmony_ci GLenum pname, GLfloat scale) 337bf215546Sopenharmony_ci{ 338bf215546Sopenharmony_ci GLuint shift; 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci if (scale == 1.0F) { 341bf215546Sopenharmony_ci shift = 0; 342bf215546Sopenharmony_ci } 343bf215546Sopenharmony_ci else if (scale == 2.0F) { 344bf215546Sopenharmony_ci shift = 1; 345bf215546Sopenharmony_ci } 346bf215546Sopenharmony_ci else if (scale == 4.0F) { 347bf215546Sopenharmony_ci shift = 2; 348bf215546Sopenharmony_ci } 349bf215546Sopenharmony_ci else { 350bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_VALUE, 351bf215546Sopenharmony_ci "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" ); 352bf215546Sopenharmony_ci return false; 353bf215546Sopenharmony_ci } 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci switch (pname) { 356bf215546Sopenharmony_ci case GL_RGB_SCALE: 357bf215546Sopenharmony_ci if (texUnit->Combine.ScaleShiftRGB == shift) 358bf215546Sopenharmony_ci return true; 359bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT); 360bf215546Sopenharmony_ci texUnit->Combine.ScaleShiftRGB = shift; 361bf215546Sopenharmony_ci break; 362bf215546Sopenharmony_ci case GL_ALPHA_SCALE: 363bf215546Sopenharmony_ci if (texUnit->Combine.ScaleShiftA == shift) 364bf215546Sopenharmony_ci return true; 365bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT); 366bf215546Sopenharmony_ci texUnit->Combine.ScaleShiftA = shift; 367bf215546Sopenharmony_ci break; 368bf215546Sopenharmony_ci default: 369bf215546Sopenharmony_ci TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 370bf215546Sopenharmony_ci return false; 371bf215546Sopenharmony_ci } 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci return true; 374bf215546Sopenharmony_ci} 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_ci 377bf215546Sopenharmony_cistatic void 378bf215546Sopenharmony_ci_mesa_texenvfv_indexed( struct gl_context* ctx, GLuint texunit, GLenum target, 379bf215546Sopenharmony_ci GLenum pname, const GLfloat *param ) 380bf215546Sopenharmony_ci{ 381bf215546Sopenharmony_ci const GLint iparam0 = (GLint) param[0]; 382bf215546Sopenharmony_ci GLuint maxUnit; 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_ci maxUnit = (target == GL_POINT_SPRITE && pname == GL_COORD_REPLACE) 385bf215546Sopenharmony_ci ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxCombinedTextureImageUnits; 386bf215546Sopenharmony_ci if (texunit >= maxUnit) { 387bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "glTexEnvfv(texunit=%d)", texunit); 388bf215546Sopenharmony_ci return; 389bf215546Sopenharmony_ci } 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_ci if (target == GL_TEXTURE_ENV) { 392bf215546Sopenharmony_ci struct gl_fixedfunc_texture_unit *texUnit = 393bf215546Sopenharmony_ci _mesa_get_fixedfunc_tex_unit(ctx, texunit); 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci /* The GL spec says that we should report an error if the unit is greater 396bf215546Sopenharmony_ci * than GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, but in practice, only 397bf215546Sopenharmony_ci * fixed-function units are usable. This is probably a spec bug. 398bf215546Sopenharmony_ci * Ignore glTexEnv(GL_TEXTURE_ENV) calls for non-fixed-func units, 399bf215546Sopenharmony_ci * because we don't want to process calls that have no effect. 400bf215546Sopenharmony_ci */ 401bf215546Sopenharmony_ci if (!texUnit) 402bf215546Sopenharmony_ci return; 403bf215546Sopenharmony_ci 404bf215546Sopenharmony_ci switch (pname) { 405bf215546Sopenharmony_ci case GL_TEXTURE_ENV_MODE: 406bf215546Sopenharmony_ci set_env_mode(ctx, texUnit, (GLenum) iparam0); 407bf215546Sopenharmony_ci break; 408bf215546Sopenharmony_ci case GL_TEXTURE_ENV_COLOR: 409bf215546Sopenharmony_ci set_env_color(ctx, texUnit, param); 410bf215546Sopenharmony_ci break; 411bf215546Sopenharmony_ci case GL_COMBINE_RGB: 412bf215546Sopenharmony_ci case GL_COMBINE_ALPHA: 413bf215546Sopenharmony_ci if (!set_combiner_mode(ctx, texUnit, pname, (GLenum) iparam0)) 414bf215546Sopenharmony_ci return; 415bf215546Sopenharmony_ci break; 416bf215546Sopenharmony_ci case GL_SOURCE0_RGB: 417bf215546Sopenharmony_ci case GL_SOURCE1_RGB: 418bf215546Sopenharmony_ci case GL_SOURCE2_RGB: 419bf215546Sopenharmony_ci case GL_SOURCE3_RGB_NV: 420bf215546Sopenharmony_ci case GL_SOURCE0_ALPHA: 421bf215546Sopenharmony_ci case GL_SOURCE1_ALPHA: 422bf215546Sopenharmony_ci case GL_SOURCE2_ALPHA: 423bf215546Sopenharmony_ci case GL_SOURCE3_ALPHA_NV: 424bf215546Sopenharmony_ci if (!set_combiner_source(ctx, texUnit, pname, (GLenum) iparam0)) 425bf215546Sopenharmony_ci return; 426bf215546Sopenharmony_ci break; 427bf215546Sopenharmony_ci case GL_OPERAND0_RGB: 428bf215546Sopenharmony_ci case GL_OPERAND1_RGB: 429bf215546Sopenharmony_ci case GL_OPERAND2_RGB: 430bf215546Sopenharmony_ci case GL_OPERAND3_RGB_NV: 431bf215546Sopenharmony_ci case GL_OPERAND0_ALPHA: 432bf215546Sopenharmony_ci case GL_OPERAND1_ALPHA: 433bf215546Sopenharmony_ci case GL_OPERAND2_ALPHA: 434bf215546Sopenharmony_ci case GL_OPERAND3_ALPHA_NV: 435bf215546Sopenharmony_ci if (!set_combiner_operand(ctx, texUnit, pname, (GLenum) iparam0)) 436bf215546Sopenharmony_ci return; 437bf215546Sopenharmony_ci break; 438bf215546Sopenharmony_ci case GL_RGB_SCALE: 439bf215546Sopenharmony_ci case GL_ALPHA_SCALE: 440bf215546Sopenharmony_ci if (!set_combiner_scale(ctx, texUnit, pname, param[0])) 441bf215546Sopenharmony_ci return; 442bf215546Sopenharmony_ci break; 443bf215546Sopenharmony_ci default: 444bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" ); 445bf215546Sopenharmony_ci return; 446bf215546Sopenharmony_ci } 447bf215546Sopenharmony_ci } 448bf215546Sopenharmony_ci else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) { 449bf215546Sopenharmony_ci struct gl_texture_unit *texUnit = 450bf215546Sopenharmony_ci _mesa_get_tex_unit(ctx, texunit); 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci if (pname == GL_TEXTURE_LOD_BIAS_EXT) { 453bf215546Sopenharmony_ci if (texUnit->LodBias == param[0]) 454bf215546Sopenharmony_ci return; 455bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, GL_TEXTURE_BIT); 456bf215546Sopenharmony_ci texUnit->LodBias = param[0]; 457bf215546Sopenharmony_ci texUnit->LodBiasQuantized = util_quantize_lod_bias(param[0]); 458bf215546Sopenharmony_ci } 459bf215546Sopenharmony_ci else { 460bf215546Sopenharmony_ci TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); 461bf215546Sopenharmony_ci return; 462bf215546Sopenharmony_ci } 463bf215546Sopenharmony_ci } 464bf215546Sopenharmony_ci else if (target == GL_POINT_SPRITE) { 465bf215546Sopenharmony_ci /* GL_ARB_point_sprite */ 466bf215546Sopenharmony_ci if (!ctx->Extensions.ARB_point_sprite) { 467bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target ); 468bf215546Sopenharmony_ci return; 469bf215546Sopenharmony_ci } 470bf215546Sopenharmony_ci if (pname == GL_COORD_REPLACE) { 471bf215546Sopenharmony_ci /* It's kind of weird to set point state via glTexEnv, 472bf215546Sopenharmony_ci * but that's what the spec calls for. 473bf215546Sopenharmony_ci */ 474bf215546Sopenharmony_ci if (iparam0 == GL_TRUE) { 475bf215546Sopenharmony_ci if (ctx->Point.CoordReplace & (1u << texunit)) 476bf215546Sopenharmony_ci return; 477bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_POINT | _NEW_FF_VERT_PROGRAM, 478bf215546Sopenharmony_ci GL_POINT_BIT); 479bf215546Sopenharmony_ci ctx->Point.CoordReplace |= (1u << texunit); 480bf215546Sopenharmony_ci } else if (iparam0 == GL_FALSE) { 481bf215546Sopenharmony_ci if (~(ctx->Point.CoordReplace) & (1u << texunit)) 482bf215546Sopenharmony_ci return; 483bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_POINT | _NEW_FF_VERT_PROGRAM, 484bf215546Sopenharmony_ci GL_POINT_BIT); 485bf215546Sopenharmony_ci ctx->Point.CoordReplace &= ~(1u << texunit); 486bf215546Sopenharmony_ci } else { 487bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", iparam0); 488bf215546Sopenharmony_ci return; 489bf215546Sopenharmony_ci } 490bf215546Sopenharmony_ci } 491bf215546Sopenharmony_ci else { 492bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname ); 493bf215546Sopenharmony_ci return; 494bf215546Sopenharmony_ci } 495bf215546Sopenharmony_ci } 496bf215546Sopenharmony_ci else { 497bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(target=%s)", 498bf215546Sopenharmony_ci _mesa_enum_to_string(target)); 499bf215546Sopenharmony_ci return; 500bf215546Sopenharmony_ci } 501bf215546Sopenharmony_ci 502bf215546Sopenharmony_ci if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) 503bf215546Sopenharmony_ci _mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n", 504bf215546Sopenharmony_ci _mesa_enum_to_string(target), 505bf215546Sopenharmony_ci _mesa_enum_to_string(pname), 506bf215546Sopenharmony_ci *param, 507bf215546Sopenharmony_ci _mesa_enum_to_string((GLenum) iparam0)); 508bf215546Sopenharmony_ci} 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_ci 511bf215546Sopenharmony_civoid GLAPIENTRY 512bf215546Sopenharmony_ci_mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) 513bf215546Sopenharmony_ci{ 514bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 515bf215546Sopenharmony_ci _mesa_texenvfv_indexed(ctx, ctx->Texture.CurrentUnit, target, pname, param); 516bf215546Sopenharmony_ci} 517bf215546Sopenharmony_ci 518bf215546Sopenharmony_ci 519bf215546Sopenharmony_civoid GLAPIENTRY 520bf215546Sopenharmony_ci_mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param ) 521bf215546Sopenharmony_ci{ 522bf215546Sopenharmony_ci GLfloat p[4]; 523bf215546Sopenharmony_ci p[0] = param; 524bf215546Sopenharmony_ci p[1] = p[2] = p[3] = 0.0; 525bf215546Sopenharmony_ci _mesa_TexEnvfv( target, pname, p ); 526bf215546Sopenharmony_ci} 527bf215546Sopenharmony_ci 528bf215546Sopenharmony_ci 529bf215546Sopenharmony_civoid GLAPIENTRY 530bf215546Sopenharmony_ci_mesa_TexEnvi( GLenum target, GLenum pname, GLint param ) 531bf215546Sopenharmony_ci{ 532bf215546Sopenharmony_ci GLfloat p[4]; 533bf215546Sopenharmony_ci p[0] = (GLfloat) param; 534bf215546Sopenharmony_ci p[1] = p[2] = p[3] = 0.0; 535bf215546Sopenharmony_ci _mesa_TexEnvfv( target, pname, p ); 536bf215546Sopenharmony_ci} 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci 539bf215546Sopenharmony_civoid GLAPIENTRY 540bf215546Sopenharmony_ci_mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param ) 541bf215546Sopenharmony_ci{ 542bf215546Sopenharmony_ci GLfloat p[4]; 543bf215546Sopenharmony_ci if (pname == GL_TEXTURE_ENV_COLOR) { 544bf215546Sopenharmony_ci p[0] = INT_TO_FLOAT( param[0] ); 545bf215546Sopenharmony_ci p[1] = INT_TO_FLOAT( param[1] ); 546bf215546Sopenharmony_ci p[2] = INT_TO_FLOAT( param[2] ); 547bf215546Sopenharmony_ci p[3] = INT_TO_FLOAT( param[3] ); 548bf215546Sopenharmony_ci } 549bf215546Sopenharmony_ci else { 550bf215546Sopenharmony_ci p[0] = (GLfloat) param[0]; 551bf215546Sopenharmony_ci p[1] = p[2] = p[3] = 0; /* init to zero, just to be safe */ 552bf215546Sopenharmony_ci } 553bf215546Sopenharmony_ci _mesa_TexEnvfv( target, pname, p ); 554bf215546Sopenharmony_ci} 555bf215546Sopenharmony_ci 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_civoid GLAPIENTRY 558bf215546Sopenharmony_ci_mesa_MultiTexEnvfEXT( GLenum texunit, GLenum target, 559bf215546Sopenharmony_ci GLenum pname, GLfloat param ) 560bf215546Sopenharmony_ci{ 561bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 562bf215546Sopenharmony_ci GLfloat p[4]; 563bf215546Sopenharmony_ci p[0] = param; 564bf215546Sopenharmony_ci p[1] = p[2] = p[3] = 0.0; 565bf215546Sopenharmony_ci _mesa_texenvfv_indexed(ctx, texunit - GL_TEXTURE0, target, pname, p); 566bf215546Sopenharmony_ci} 567bf215546Sopenharmony_ci 568bf215546Sopenharmony_civoid GLAPIENTRY 569bf215546Sopenharmony_ci_mesa_MultiTexEnvfvEXT( GLenum texunit, GLenum target, 570bf215546Sopenharmony_ci GLenum pname, const GLfloat *param ) 571bf215546Sopenharmony_ci{ 572bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 573bf215546Sopenharmony_ci _mesa_texenvfv_indexed(ctx, texunit - GL_TEXTURE0, target, pname, param); 574bf215546Sopenharmony_ci} 575bf215546Sopenharmony_ci 576bf215546Sopenharmony_ci 577bf215546Sopenharmony_civoid GLAPIENTRY 578bf215546Sopenharmony_ci_mesa_MultiTexEnviEXT( GLenum texunit, GLenum target, 579bf215546Sopenharmony_ci GLenum pname, GLint param ) 580bf215546Sopenharmony_ci{ 581bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 582bf215546Sopenharmony_ci GLfloat p[4]; 583bf215546Sopenharmony_ci p[0] = (GLfloat) param; 584bf215546Sopenharmony_ci p[1] = p[2] = p[3] = 0.0; 585bf215546Sopenharmony_ci _mesa_texenvfv_indexed( ctx, texunit - GL_TEXTURE0, target, pname, p ); 586bf215546Sopenharmony_ci} 587bf215546Sopenharmony_ci 588bf215546Sopenharmony_ci 589bf215546Sopenharmony_civoid GLAPIENTRY 590bf215546Sopenharmony_ci_mesa_MultiTexEnvivEXT( GLenum texunit, GLenum target, 591bf215546Sopenharmony_ci GLenum pname, const GLint *param ) 592bf215546Sopenharmony_ci{ 593bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 594bf215546Sopenharmony_ci GLfloat p[4]; 595bf215546Sopenharmony_ci if (pname == GL_TEXTURE_ENV_COLOR) { 596bf215546Sopenharmony_ci p[0] = INT_TO_FLOAT( param[0] ); 597bf215546Sopenharmony_ci p[1] = INT_TO_FLOAT( param[1] ); 598bf215546Sopenharmony_ci p[2] = INT_TO_FLOAT( param[2] ); 599bf215546Sopenharmony_ci p[3] = INT_TO_FLOAT( param[3] ); 600bf215546Sopenharmony_ci } 601bf215546Sopenharmony_ci else { 602bf215546Sopenharmony_ci p[0] = (GLfloat) param[0]; 603bf215546Sopenharmony_ci p[1] = p[2] = p[3] = 0; /* init to zero, just to be safe */ 604bf215546Sopenharmony_ci } 605bf215546Sopenharmony_ci _mesa_texenvfv_indexed( ctx, texunit - GL_TEXTURE0, target, pname, p ); 606bf215546Sopenharmony_ci} 607bf215546Sopenharmony_ci 608bf215546Sopenharmony_ci 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci 611bf215546Sopenharmony_ci/** 612bf215546Sopenharmony_ci * Helper for glGetTexEnvi/f() 613bf215546Sopenharmony_ci * \return value of queried pname or -1 if error. 614bf215546Sopenharmony_ci */ 615bf215546Sopenharmony_cistatic GLint 616bf215546Sopenharmony_ciget_texenvi(struct gl_context *ctx, 617bf215546Sopenharmony_ci const struct gl_fixedfunc_texture_unit *texUnit, 618bf215546Sopenharmony_ci GLenum pname) 619bf215546Sopenharmony_ci{ 620bf215546Sopenharmony_ci switch (pname) { 621bf215546Sopenharmony_ci case GL_TEXTURE_ENV_MODE: 622bf215546Sopenharmony_ci return texUnit->EnvMode; 623bf215546Sopenharmony_ci break; 624bf215546Sopenharmony_ci case GL_COMBINE_RGB: 625bf215546Sopenharmony_ci return texUnit->Combine.ModeRGB; 626bf215546Sopenharmony_ci case GL_COMBINE_ALPHA: 627bf215546Sopenharmony_ci return texUnit->Combine.ModeA; 628bf215546Sopenharmony_ci case GL_SOURCE0_RGB: 629bf215546Sopenharmony_ci case GL_SOURCE1_RGB: 630bf215546Sopenharmony_ci case GL_SOURCE2_RGB: { 631bf215546Sopenharmony_ci const unsigned rgb_idx = pname - GL_SOURCE0_RGB; 632bf215546Sopenharmony_ci return texUnit->Combine.SourceRGB[rgb_idx]; 633bf215546Sopenharmony_ci } 634bf215546Sopenharmony_ci case GL_SOURCE3_RGB_NV: 635bf215546Sopenharmony_ci if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.NV_texture_env_combine4) { 636bf215546Sopenharmony_ci return texUnit->Combine.SourceRGB[3]; 637bf215546Sopenharmony_ci } 638bf215546Sopenharmony_ci else { 639bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 640bf215546Sopenharmony_ci } 641bf215546Sopenharmony_ci break; 642bf215546Sopenharmony_ci case GL_SOURCE0_ALPHA: 643bf215546Sopenharmony_ci case GL_SOURCE1_ALPHA: 644bf215546Sopenharmony_ci case GL_SOURCE2_ALPHA: { 645bf215546Sopenharmony_ci const unsigned alpha_idx = pname - GL_SOURCE0_ALPHA; 646bf215546Sopenharmony_ci return texUnit->Combine.SourceA[alpha_idx]; 647bf215546Sopenharmony_ci } 648bf215546Sopenharmony_ci case GL_SOURCE3_ALPHA_NV: 649bf215546Sopenharmony_ci if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.NV_texture_env_combine4) { 650bf215546Sopenharmony_ci return texUnit->Combine.SourceA[3]; 651bf215546Sopenharmony_ci } 652bf215546Sopenharmony_ci else { 653bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 654bf215546Sopenharmony_ci } 655bf215546Sopenharmony_ci break; 656bf215546Sopenharmony_ci case GL_OPERAND0_RGB: 657bf215546Sopenharmony_ci case GL_OPERAND1_RGB: 658bf215546Sopenharmony_ci case GL_OPERAND2_RGB: { 659bf215546Sopenharmony_ci const unsigned op_rgb = pname - GL_OPERAND0_RGB; 660bf215546Sopenharmony_ci return texUnit->Combine.OperandRGB[op_rgb]; 661bf215546Sopenharmony_ci } 662bf215546Sopenharmony_ci case GL_OPERAND3_RGB_NV: 663bf215546Sopenharmony_ci if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.NV_texture_env_combine4) { 664bf215546Sopenharmony_ci return texUnit->Combine.OperandRGB[3]; 665bf215546Sopenharmony_ci } 666bf215546Sopenharmony_ci else { 667bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 668bf215546Sopenharmony_ci } 669bf215546Sopenharmony_ci break; 670bf215546Sopenharmony_ci case GL_OPERAND0_ALPHA: 671bf215546Sopenharmony_ci case GL_OPERAND1_ALPHA: 672bf215546Sopenharmony_ci case GL_OPERAND2_ALPHA: { 673bf215546Sopenharmony_ci const unsigned op_alpha = pname - GL_OPERAND0_ALPHA; 674bf215546Sopenharmony_ci return texUnit->Combine.OperandA[op_alpha]; 675bf215546Sopenharmony_ci } 676bf215546Sopenharmony_ci case GL_OPERAND3_ALPHA_NV: 677bf215546Sopenharmony_ci if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.NV_texture_env_combine4) { 678bf215546Sopenharmony_ci return texUnit->Combine.OperandA[3]; 679bf215546Sopenharmony_ci } 680bf215546Sopenharmony_ci else { 681bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 682bf215546Sopenharmony_ci } 683bf215546Sopenharmony_ci break; 684bf215546Sopenharmony_ci case GL_RGB_SCALE: 685bf215546Sopenharmony_ci return 1 << texUnit->Combine.ScaleShiftRGB; 686bf215546Sopenharmony_ci case GL_ALPHA_SCALE: 687bf215546Sopenharmony_ci return 1 << texUnit->Combine.ScaleShiftA; 688bf215546Sopenharmony_ci default: 689bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); 690bf215546Sopenharmony_ci break; 691bf215546Sopenharmony_ci } 692bf215546Sopenharmony_ci 693bf215546Sopenharmony_ci return -1; /* error */ 694bf215546Sopenharmony_ci} 695bf215546Sopenharmony_ci 696bf215546Sopenharmony_ci 697bf215546Sopenharmony_cistatic void 698bf215546Sopenharmony_ci_mesa_gettexenvfv_indexed( GLuint texunit, GLenum target, GLenum pname, GLfloat *params ) 699bf215546Sopenharmony_ci{ 700bf215546Sopenharmony_ci GLuint maxUnit; 701bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 702bf215546Sopenharmony_ci 703bf215546Sopenharmony_ci maxUnit = (target == GL_POINT_SPRITE && pname == GL_COORD_REPLACE) 704bf215546Sopenharmony_ci ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxCombinedTextureImageUnits; 705bf215546Sopenharmony_ci if (texunit >= maxUnit) { 706bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnvfv(texunit=%d)", texunit); 707bf215546Sopenharmony_ci return; 708bf215546Sopenharmony_ci } 709bf215546Sopenharmony_ci 710bf215546Sopenharmony_ci if (target == GL_TEXTURE_ENV) { 711bf215546Sopenharmony_ci struct gl_fixedfunc_texture_unit *texUnit = 712bf215546Sopenharmony_ci _mesa_get_fixedfunc_tex_unit(ctx, texunit); 713bf215546Sopenharmony_ci 714bf215546Sopenharmony_ci /* The GL spec says that we should report an error if the unit is greater 715bf215546Sopenharmony_ci * than GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, but in practice, only 716bf215546Sopenharmony_ci * fixed-function units are usable. This is probably a spec bug. 717bf215546Sopenharmony_ci * Ignore calls for non-fixed-func units, because we don't process 718bf215546Sopenharmony_ci * glTexEnv for them either. 719bf215546Sopenharmony_ci */ 720bf215546Sopenharmony_ci if (!texUnit) 721bf215546Sopenharmony_ci return; 722bf215546Sopenharmony_ci 723bf215546Sopenharmony_ci if (pname == GL_TEXTURE_ENV_COLOR) { 724bf215546Sopenharmony_ci if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer)) 725bf215546Sopenharmony_ci COPY_4FV( params, texUnit->EnvColor ); 726bf215546Sopenharmony_ci else 727bf215546Sopenharmony_ci COPY_4FV( params, texUnit->EnvColorUnclamped ); 728bf215546Sopenharmony_ci } 729bf215546Sopenharmony_ci else { 730bf215546Sopenharmony_ci GLint val = get_texenvi(ctx, texUnit, pname); 731bf215546Sopenharmony_ci if (val >= 0) { 732bf215546Sopenharmony_ci *params = (GLfloat) val; 733bf215546Sopenharmony_ci } 734bf215546Sopenharmony_ci } 735bf215546Sopenharmony_ci } 736bf215546Sopenharmony_ci else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) { 737bf215546Sopenharmony_ci const struct gl_texture_unit *texUnit = _mesa_get_tex_unit(ctx, texunit); 738bf215546Sopenharmony_ci 739bf215546Sopenharmony_ci if (pname == GL_TEXTURE_LOD_BIAS_EXT) { 740bf215546Sopenharmony_ci *params = texUnit->LodBias; 741bf215546Sopenharmony_ci } 742bf215546Sopenharmony_ci else { 743bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" ); 744bf215546Sopenharmony_ci return; 745bf215546Sopenharmony_ci } 746bf215546Sopenharmony_ci } 747bf215546Sopenharmony_ci else if (target == GL_POINT_SPRITE) { 748bf215546Sopenharmony_ci /* GL_ARB_point_sprite */ 749bf215546Sopenharmony_ci if (!ctx->Extensions.ARB_point_sprite) { 750bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" ); 751bf215546Sopenharmony_ci return; 752bf215546Sopenharmony_ci } 753bf215546Sopenharmony_ci if (pname == GL_COORD_REPLACE) { 754bf215546Sopenharmony_ci if (ctx->Point.CoordReplace & (1u << texunit)) 755bf215546Sopenharmony_ci *params = 1.0f; 756bf215546Sopenharmony_ci else 757bf215546Sopenharmony_ci *params = 0.0f; 758bf215546Sopenharmony_ci } 759bf215546Sopenharmony_ci else { 760bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" ); 761bf215546Sopenharmony_ci return; 762bf215546Sopenharmony_ci } 763bf215546Sopenharmony_ci } 764bf215546Sopenharmony_ci else { 765bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" ); 766bf215546Sopenharmony_ci return; 767bf215546Sopenharmony_ci } 768bf215546Sopenharmony_ci} 769bf215546Sopenharmony_ci 770bf215546Sopenharmony_ci 771bf215546Sopenharmony_cistatic void 772bf215546Sopenharmony_ci_mesa_gettexenviv_indexed( GLuint texunit, GLenum target, 773bf215546Sopenharmony_ci GLenum pname, GLint *params ) 774bf215546Sopenharmony_ci{ 775bf215546Sopenharmony_ci GLuint maxUnit; 776bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci maxUnit = (target == GL_POINT_SPRITE && pname == GL_COORD_REPLACE) 779bf215546Sopenharmony_ci ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxCombinedTextureImageUnits; 780bf215546Sopenharmony_ci if (texunit >= maxUnit) { 781bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnviv(texunit=%d)", 782bf215546Sopenharmony_ci texunit); 783bf215546Sopenharmony_ci return; 784bf215546Sopenharmony_ci } 785bf215546Sopenharmony_ci 786bf215546Sopenharmony_ci if (target == GL_TEXTURE_ENV) { 787bf215546Sopenharmony_ci struct gl_fixedfunc_texture_unit *texUnit = 788bf215546Sopenharmony_ci _mesa_get_fixedfunc_tex_unit(ctx, texunit); 789bf215546Sopenharmony_ci 790bf215546Sopenharmony_ci /* The GL spec says that we should report an error if the unit is greater 791bf215546Sopenharmony_ci * than GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, but in practice, only 792bf215546Sopenharmony_ci * fixed-function units are usable. This is probably a spec bug. 793bf215546Sopenharmony_ci * Ignore calls for non-fixed-func units, because we don't process 794bf215546Sopenharmony_ci * glTexEnv for them either. 795bf215546Sopenharmony_ci */ 796bf215546Sopenharmony_ci if (!texUnit) 797bf215546Sopenharmony_ci return; 798bf215546Sopenharmony_ci 799bf215546Sopenharmony_ci if (pname == GL_TEXTURE_ENV_COLOR) { 800bf215546Sopenharmony_ci params[0] = FLOAT_TO_INT( texUnit->EnvColor[0] ); 801bf215546Sopenharmony_ci params[1] = FLOAT_TO_INT( texUnit->EnvColor[1] ); 802bf215546Sopenharmony_ci params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] ); 803bf215546Sopenharmony_ci params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] ); 804bf215546Sopenharmony_ci } 805bf215546Sopenharmony_ci else { 806bf215546Sopenharmony_ci GLint val = get_texenvi(ctx, texUnit, pname); 807bf215546Sopenharmony_ci if (val >= 0) { 808bf215546Sopenharmony_ci *params = val; 809bf215546Sopenharmony_ci } 810bf215546Sopenharmony_ci } 811bf215546Sopenharmony_ci } 812bf215546Sopenharmony_ci else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) { 813bf215546Sopenharmony_ci const struct gl_texture_unit *texUnit = _mesa_get_tex_unit(ctx, texunit); 814bf215546Sopenharmony_ci 815bf215546Sopenharmony_ci if (pname == GL_TEXTURE_LOD_BIAS_EXT) { 816bf215546Sopenharmony_ci *params = (GLint) texUnit->LodBias; 817bf215546Sopenharmony_ci } 818bf215546Sopenharmony_ci else { 819bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" ); 820bf215546Sopenharmony_ci return; 821bf215546Sopenharmony_ci } 822bf215546Sopenharmony_ci } 823bf215546Sopenharmony_ci else if (target == GL_POINT_SPRITE) { 824bf215546Sopenharmony_ci /* GL_ARB_point_sprite */ 825bf215546Sopenharmony_ci if (!ctx->Extensions.ARB_point_sprite) { 826bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" ); 827bf215546Sopenharmony_ci return; 828bf215546Sopenharmony_ci } 829bf215546Sopenharmony_ci if (pname == GL_COORD_REPLACE) { 830bf215546Sopenharmony_ci if (ctx->Point.CoordReplace & (1u << texunit)) 831bf215546Sopenharmony_ci *params = GL_TRUE; 832bf215546Sopenharmony_ci else 833bf215546Sopenharmony_ci *params = GL_FALSE; 834bf215546Sopenharmony_ci } 835bf215546Sopenharmony_ci else { 836bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" ); 837bf215546Sopenharmony_ci return; 838bf215546Sopenharmony_ci } 839bf215546Sopenharmony_ci } 840bf215546Sopenharmony_ci else { 841bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" ); 842bf215546Sopenharmony_ci return; 843bf215546Sopenharmony_ci } 844bf215546Sopenharmony_ci} 845bf215546Sopenharmony_ci 846bf215546Sopenharmony_ci 847bf215546Sopenharmony_civoid GLAPIENTRY 848bf215546Sopenharmony_ci_mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) 849bf215546Sopenharmony_ci{ 850bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 851bf215546Sopenharmony_ci _mesa_gettexenvfv_indexed(ctx->Texture.CurrentUnit, target, pname, params); 852bf215546Sopenharmony_ci} 853bf215546Sopenharmony_ci 854bf215546Sopenharmony_ci 855bf215546Sopenharmony_civoid GLAPIENTRY 856bf215546Sopenharmony_ci_mesa_GetMultiTexEnvfvEXT( GLenum texunit, GLenum target, 857bf215546Sopenharmony_ci GLenum pname, GLfloat *params ) 858bf215546Sopenharmony_ci{ 859bf215546Sopenharmony_ci _mesa_gettexenvfv_indexed(texunit - GL_TEXTURE0, target, pname, params); 860bf215546Sopenharmony_ci} 861bf215546Sopenharmony_ci 862bf215546Sopenharmony_ci 863bf215546Sopenharmony_civoid GLAPIENTRY 864bf215546Sopenharmony_ci_mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) 865bf215546Sopenharmony_ci{ 866bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 867bf215546Sopenharmony_ci _mesa_gettexenviv_indexed(ctx->Texture.CurrentUnit, target, pname, params); 868bf215546Sopenharmony_ci} 869bf215546Sopenharmony_ci 870bf215546Sopenharmony_ci 871bf215546Sopenharmony_civoid GLAPIENTRY 872bf215546Sopenharmony_ci_mesa_GetMultiTexEnvivEXT( GLenum texunit, GLenum target, 873bf215546Sopenharmony_ci GLenum pname, GLint *params ) 874bf215546Sopenharmony_ci{ 875bf215546Sopenharmony_ci _mesa_gettexenviv_indexed(texunit - GL_TEXTURE0, target, pname, params); 876bf215546Sopenharmony_ci} 877