s_texcombine.c revision 81ca8b93f212d1946c70660041ce97d98f352608
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.5 4 * 5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 27#include "main/glheader.h" 28#include "main/context.h" 29#include "main/colormac.h" 30#include "main/image.h" 31#include "main/imports.h" 32#include "main/macros.h" 33#include "main/pixel.h" 34#include "shader/prog_instruction.h" 35 36#include "s_context.h" 37#include "s_texcombine.h" 38 39 40#define PROD(A,B) ( (GLuint)(A) * ((GLuint)(B)+1) ) 41#define S_PROD(A,B) ( (GLint)(A) * ((GLint)(B)+1) ) 42#if CHAN_BITS == 32 43typedef GLfloat ChanTemp; 44#else 45typedef GLuint ChanTemp; 46#endif 47 48 49/** 50 * Do texture application for GL_ARB/EXT_texture_env_combine. 51 * This function also supports GL_{EXT,ARB}_texture_env_dot3 and 52 * GL_ATI_texture_env_combine3. Since "classic" texture environments are 53 * implemented using GL_ARB_texture_env_combine-like state, this same function 54 * is used for classic texture environment application as well. 55 * 56 * \param ctx rendering context 57 * \param textureUnit the texture unit to apply 58 * \param n number of fragments to process (span width) 59 * \param primary_rgba incoming fragment color array 60 * \param texelBuffer pointer to texel colors for all texture units 61 * 62 * \param rgba incoming colors, which get modified here 63 */ 64static void 65texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, 66 CONST GLchan (*primary_rgba)[4], 67 CONST GLchan *texelBuffer, 68 GLchan (*rgba)[4] ) 69{ 70 const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]); 71 const GLchan (*argRGB [4])[4]; 72 const GLchan (*argA [4])[4]; 73 const GLint RGBshift = textureUnit->_CurrentCombine->ScaleShiftRGB; 74 const GLuint Ashift = textureUnit->_CurrentCombine->ScaleShiftA; 75#if CHAN_TYPE == GL_FLOAT 76 const GLchan RGBmult = (GLfloat) (1 << RGBshift); 77 const GLchan Amult = (GLfloat) (1 << Ashift); 78#else 79 const GLint half = (CHAN_MAX + 1) / 2; 80#endif 81 static const GLchan one[4] = { CHAN_MAX, CHAN_MAX, CHAN_MAX, CHAN_MAX }; 82 static const GLchan zero[4] = { 0, 0, 0, 0 }; 83 const GLuint numColorArgs = textureUnit->_CurrentCombine->_NumArgsRGB; 84 const GLuint numAlphaArgs = textureUnit->_CurrentCombine->_NumArgsA; 85 GLchan ccolor[4][MAX_WIDTH][4]; 86 GLuint i, j; 87 88 ASSERT(ctx->Extensions.EXT_texture_env_combine || 89 ctx->Extensions.ARB_texture_env_combine); 90 ASSERT(CONST_SWRAST_CONTEXT(ctx)->_AnyTextureCombine); 91 92 /* 93 printf("modeRGB 0x%x modeA 0x%x srcRGB1 0x%x srcA1 0x%x srcRGB2 0x%x srcA2 0x%x\n", 94 textureUnit->_CurrentCombine->ModeRGB, 95 textureUnit->_CurrentCombine->ModeA, 96 textureUnit->_CurrentCombine->SourceRGB[0], 97 textureUnit->_CurrentCombine->SourceA[0], 98 textureUnit->_CurrentCombine->SourceRGB[1], 99 textureUnit->_CurrentCombine->SourceA[1]); 100 */ 101 102 /* 103 * Do operand setup for up to 4 operands. Loop over the terms. 104 */ 105 for (j = 0; j < numColorArgs; j++) { 106 const GLenum srcRGB = textureUnit->_CurrentCombine->SourceRGB[j]; 107 108 switch (srcRGB) { 109 case GL_TEXTURE: 110 argRGB[j] = (const GLchan (*)[4]) 111 (texelBuffer + unit * (n * 4 * sizeof(GLchan))); 112 break; 113 case GL_PRIMARY_COLOR: 114 argRGB[j] = primary_rgba; 115 break; 116 case GL_PREVIOUS: 117 argRGB[j] = (const GLchan (*)[4]) rgba; 118 break; 119 case GL_CONSTANT: 120 { 121 GLchan (*c)[4] = ccolor[j]; 122 GLchan red, green, blue, alpha; 123 UNCLAMPED_FLOAT_TO_CHAN(red, textureUnit->EnvColor[0]); 124 UNCLAMPED_FLOAT_TO_CHAN(green, textureUnit->EnvColor[1]); 125 UNCLAMPED_FLOAT_TO_CHAN(blue, textureUnit->EnvColor[2]); 126 UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]); 127 for (i = 0; i < n; i++) { 128 c[i][RCOMP] = red; 129 c[i][GCOMP] = green; 130 c[i][BCOMP] = blue; 131 c[i][ACOMP] = alpha; 132 } 133 argRGB[j] = (const GLchan (*)[4]) ccolor[j]; 134 } 135 break; 136 /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources. 137 */ 138 case GL_ZERO: 139 argRGB[j] = & zero; 140 break; 141 case GL_ONE: 142 argRGB[j] = & one; 143 break; 144 default: 145 /* ARB_texture_env_crossbar source */ 146 { 147 const GLuint srcUnit = srcRGB - GL_TEXTURE0; 148 ASSERT(srcUnit < ctx->Const.MaxTextureUnits); 149 if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled) 150 return; 151 argRGB[j] = (const GLchan (*)[4]) 152 (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan))); 153 } 154 } 155 156 if (textureUnit->_CurrentCombine->OperandRGB[j] != GL_SRC_COLOR) { 157 const GLchan (*src)[4] = argRGB[j]; 158 GLchan (*dst)[4] = ccolor[j]; 159 160 /* point to new arg[j] storage */ 161 argRGB[j] = (const GLchan (*)[4]) ccolor[j]; 162 163 if (textureUnit->_CurrentCombine->OperandRGB[j] == GL_ONE_MINUS_SRC_COLOR) { 164 for (i = 0; i < n; i++) { 165 dst[i][RCOMP] = CHAN_MAX - src[i][RCOMP]; 166 dst[i][GCOMP] = CHAN_MAX - src[i][GCOMP]; 167 dst[i][BCOMP] = CHAN_MAX - src[i][BCOMP]; 168 } 169 } 170 else if (textureUnit->_CurrentCombine->OperandRGB[j] == GL_SRC_ALPHA) { 171 for (i = 0; i < n; i++) { 172 dst[i][RCOMP] = src[i][ACOMP]; 173 dst[i][GCOMP] = src[i][ACOMP]; 174 dst[i][BCOMP] = src[i][ACOMP]; 175 } 176 } 177 else { 178 ASSERT(textureUnit->_CurrentCombine->OperandRGB[j] ==GL_ONE_MINUS_SRC_ALPHA); 179 for (i = 0; i < n; i++) { 180 dst[i][RCOMP] = CHAN_MAX - src[i][ACOMP]; 181 dst[i][GCOMP] = CHAN_MAX - src[i][ACOMP]; 182 dst[i][BCOMP] = CHAN_MAX - src[i][ACOMP]; 183 } 184 } 185 } 186 } 187 188 /* 189 * Set up the argA[i] pointers 190 */ 191 for (j = 0; j < numAlphaArgs; j++) { 192 const GLenum srcA = textureUnit->_CurrentCombine->SourceA[j]; 193 194 switch (srcA) { 195 case GL_TEXTURE: 196 argA[j] = (const GLchan (*)[4]) 197 (texelBuffer + unit * (n * 4 * sizeof(GLchan))); 198 break; 199 case GL_PRIMARY_COLOR: 200 argA[j] = primary_rgba; 201 break; 202 case GL_PREVIOUS: 203 argA[j] = (const GLchan (*)[4]) rgba; 204 break; 205 case GL_CONSTANT: 206 { 207 GLchan alpha, (*c)[4] = ccolor[j]; 208 UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]); 209 for (i = 0; i < n; i++) 210 c[i][ACOMP] = alpha; 211 argA[j] = (const GLchan (*)[4]) ccolor[j]; 212 } 213 break; 214 /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources. 215 */ 216 case GL_ZERO: 217 argA[j] = & zero; 218 break; 219 case GL_ONE: 220 argA[j] = & one; 221 break; 222 default: 223 /* ARB_texture_env_crossbar source */ 224 { 225 const GLuint srcUnit = srcA - GL_TEXTURE0; 226 ASSERT(srcUnit < ctx->Const.MaxTextureUnits); 227 if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled) 228 return; 229 argA[j] = (const GLchan (*)[4]) 230 (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan))); 231 } 232 } 233 234 if (textureUnit->_CurrentCombine->OperandA[j] == GL_ONE_MINUS_SRC_ALPHA) { 235 const GLchan (*src)[4] = argA[j]; 236 GLchan (*dst)[4] = ccolor[j]; 237 argA[j] = (const GLchan (*)[4]) ccolor[j]; 238 for (i = 0; i < n; i++) { 239 dst[i][ACOMP] = CHAN_MAX - src[i][ACOMP]; 240 } 241 } 242 } 243 244 /* 245 * Do the texture combine. 246 */ 247 switch (textureUnit->_CurrentCombine->ModeRGB) { 248 case GL_REPLACE: 249 { 250 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 251 if (RGBshift) { 252 for (i = 0; i < n; i++) { 253#if CHAN_TYPE == GL_FLOAT 254 rgba[i][RCOMP] = arg0[i][RCOMP] * RGBmult; 255 rgba[i][GCOMP] = arg0[i][GCOMP] * RGBmult; 256 rgba[i][BCOMP] = arg0[i][BCOMP] * RGBmult; 257#else 258 GLuint r = (GLuint) arg0[i][RCOMP] << RGBshift; 259 GLuint g = (GLuint) arg0[i][GCOMP] << RGBshift; 260 GLuint b = (GLuint) arg0[i][BCOMP] << RGBshift; 261 rgba[i][RCOMP] = MIN2(r, CHAN_MAX); 262 rgba[i][GCOMP] = MIN2(g, CHAN_MAX); 263 rgba[i][BCOMP] = MIN2(b, CHAN_MAX); 264#endif 265 } 266 } 267 else { 268 for (i = 0; i < n; i++) { 269 rgba[i][RCOMP] = arg0[i][RCOMP]; 270 rgba[i][GCOMP] = arg0[i][GCOMP]; 271 rgba[i][BCOMP] = arg0[i][BCOMP]; 272 } 273 } 274 } 275 break; 276 case GL_MODULATE: 277 { 278 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 279 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 280#if CHAN_TYPE != GL_FLOAT 281 const GLint shift = CHAN_BITS - RGBshift; 282#endif 283 for (i = 0; i < n; i++) { 284#if CHAN_TYPE == GL_FLOAT 285 rgba[i][RCOMP] = arg0[i][RCOMP] * arg1[i][RCOMP] * RGBmult; 286 rgba[i][GCOMP] = arg0[i][GCOMP] * arg1[i][GCOMP] * RGBmult; 287 rgba[i][BCOMP] = arg0[i][BCOMP] * arg1[i][BCOMP] * RGBmult; 288#else 289 GLuint r = PROD(arg0[i][RCOMP], arg1[i][RCOMP]) >> shift; 290 GLuint g = PROD(arg0[i][GCOMP], arg1[i][GCOMP]) >> shift; 291 GLuint b = PROD(arg0[i][BCOMP], arg1[i][BCOMP]) >> shift; 292 rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); 293 rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); 294 rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); 295#endif 296 } 297 } 298 break; 299 case GL_ADD: 300 if (textureUnit->EnvMode == GL_COMBINE4_NV) { 301 /* (a * b) + (c * d) */ 302 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 303 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 304 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2]; 305 const GLchan (*arg3)[4] = (const GLchan (*)[4]) argRGB[3]; 306 for (i = 0; i < n; i++) { 307#if CHAN_TYPE == GL_FLOAT 308 rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] + 309 arg2[i][RCOMP] * arg3[i][RCOMP]) * RGBmult; 310 rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] + 311 arg2[i][GCOMP] * arg3[i][GCOMP]) * RGBmult; 312 rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] + 313 arg2[i][BCOMP] * arg3[i][BCOMP]) * RGBmult; 314#else 315 const GLint shift = CHAN_BITS - RGBshift; 316 GLint r = (PROD(arg0[i][RCOMP], arg1[i][RCOMP]) >> shift) + 317 (PROD(arg2[i][RCOMP], arg3[i][RCOMP]) >> shift); 318 GLint g = (PROD(arg0[i][GCOMP], arg1[i][GCOMP]) >> shift) + 319 (PROD(arg2[i][GCOMP], arg3[i][GCOMP]) >> shift); 320 GLint b = (PROD(arg0[i][BCOMP], arg1[i][BCOMP]) >> shift) + 321 (PROD(arg2[i][BCOMP], arg3[i][BCOMP]) >> shift); 322 rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); 323 rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); 324 rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); 325#endif 326 } 327 } 328 else { 329 /* 2-term addition */ 330 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 331 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 332 for (i = 0; i < n; i++) { 333#if CHAN_TYPE == GL_FLOAT 334 rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP]) * RGBmult; 335 rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP]) * RGBmult; 336 rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP]) * RGBmult; 337#else 338 GLint r = ((GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP]) << RGBshift; 339 GLint g = ((GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP]) << RGBshift; 340 GLint b = ((GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP]) << RGBshift; 341 rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); 342 rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); 343 rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); 344#endif 345 } 346 } 347 break; 348 case GL_ADD_SIGNED: 349 if (textureUnit->EnvMode == GL_COMBINE4_NV) { 350 /* (a * b) + (c * d) - 0.5 */ 351 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 352 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 353 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2]; 354 const GLchan (*arg3)[4] = (const GLchan (*)[4]) argRGB[3]; 355 for (i = 0; i < n; i++) { 356#if CHAN_TYPE == GL_FLOAT 357 rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] * 358 arg2[i][RCOMP] + arg3[i][RCOMP] - 0.5) * RGBmult; 359 rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] * 360 arg2[i][GCOMP] + arg3[i][GCOMP] - 0.5) * RGBmult; 361 rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] * 362 arg2[i][BCOMP] + arg3[i][BCOMP] - 0.5) * RGBmult; 363#else 364 GLint r = (((PROD(arg0[i][RCOMP], arg1[i][RCOMP]) + 365 PROD(arg2[i][RCOMP], arg3[i][RCOMP])) >> CHAN_BITS) - half) 366 << RGBshift; 367 GLint g = (((PROD(arg0[i][GCOMP], arg1[i][GCOMP]) + 368 PROD(arg2[i][GCOMP], arg3[i][GCOMP])) >> CHAN_BITS) - half) 369 << RGBshift; 370 GLint b = (((PROD(arg0[i][BCOMP], arg1[i][BCOMP]) + 371 PROD(arg2[i][BCOMP], arg3[i][BCOMP])) >> CHAN_BITS) - half) 372 << RGBshift; 373 rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); 374 rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); 375 rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); 376#endif 377 } 378 } 379 else { 380 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 381 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 382 for (i = 0; i < n; i++) { 383#if CHAN_TYPE == GL_FLOAT 384 rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] - 0.5) * RGBmult; 385 rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] - 0.5) * RGBmult; 386 rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] - 0.5) * RGBmult; 387#else 388 GLint r = (GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP] - half; 389 GLint g = (GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP] - half; 390 GLint b = (GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP] - half; 391 r = (r < 0) ? 0 : r << RGBshift; 392 g = (g < 0) ? 0 : g << RGBshift; 393 b = (b < 0) ? 0 : b << RGBshift; 394 rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); 395 rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); 396 rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); 397#endif 398 } 399 } 400 break; 401 case GL_INTERPOLATE: 402 { 403 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 404 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 405 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2]; 406#if CHAN_TYPE != GL_FLOAT 407 const GLint shift = CHAN_BITS - RGBshift; 408#endif 409 for (i = 0; i < n; i++) { 410#if CHAN_TYPE == GL_FLOAT 411 rgba[i][RCOMP] = (arg0[i][RCOMP] * arg2[i][RCOMP] + 412 arg1[i][RCOMP] * (CHAN_MAXF - arg2[i][RCOMP])) * RGBmult; 413 rgba[i][GCOMP] = (arg0[i][GCOMP] * arg2[i][GCOMP] + 414 arg1[i][GCOMP] * (CHAN_MAXF - arg2[i][GCOMP])) * RGBmult; 415 rgba[i][BCOMP] = (arg0[i][BCOMP] * arg2[i][BCOMP] + 416 arg1[i][BCOMP] * (CHAN_MAXF - arg2[i][BCOMP])) * RGBmult; 417#else 418 GLuint r = (PROD(arg0[i][RCOMP], arg2[i][RCOMP]) 419 + PROD(arg1[i][RCOMP], CHAN_MAX - arg2[i][RCOMP])) 420 >> shift; 421 GLuint g = (PROD(arg0[i][GCOMP], arg2[i][GCOMP]) 422 + PROD(arg1[i][GCOMP], CHAN_MAX - arg2[i][GCOMP])) 423 >> shift; 424 GLuint b = (PROD(arg0[i][BCOMP], arg2[i][BCOMP]) 425 + PROD(arg1[i][BCOMP], CHAN_MAX - arg2[i][BCOMP])) 426 >> shift; 427 rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); 428 rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); 429 rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); 430#endif 431 } 432 } 433 break; 434 case GL_SUBTRACT: 435 { 436 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 437 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 438 for (i = 0; i < n; i++) { 439#if CHAN_TYPE == GL_FLOAT 440 rgba[i][RCOMP] = (arg0[i][RCOMP] - arg1[i][RCOMP]) * RGBmult; 441 rgba[i][GCOMP] = (arg0[i][GCOMP] - arg1[i][GCOMP]) * RGBmult; 442 rgba[i][BCOMP] = (arg0[i][BCOMP] - arg1[i][BCOMP]) * RGBmult; 443#else 444 GLint r = ((GLint) arg0[i][RCOMP] - (GLint) arg1[i][RCOMP]) << RGBshift; 445 GLint g = ((GLint) arg0[i][GCOMP] - (GLint) arg1[i][GCOMP]) << RGBshift; 446 GLint b = ((GLint) arg0[i][BCOMP] - (GLint) arg1[i][BCOMP]) << RGBshift; 447 rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); 448 rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); 449 rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); 450#endif 451 } 452 } 453 break; 454 case GL_DOT3_RGB_EXT: 455 case GL_DOT3_RGBA_EXT: 456 { 457 /* Do not scale the result by 1 2 or 4 */ 458 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 459 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 460 for (i = 0; i < n; i++) { 461#if CHAN_TYPE == GL_FLOAT 462 GLchan dot = ((arg0[i][RCOMP]-0.5F) * (arg1[i][RCOMP]-0.5F) + 463 (arg0[i][GCOMP]-0.5F) * (arg1[i][GCOMP]-0.5F) + 464 (arg0[i][BCOMP]-0.5F) * (arg1[i][BCOMP]-0.5F)) 465 * 4.0F; 466 dot = CLAMP(dot, 0.0F, CHAN_MAXF); 467#else 468 GLint dot = (S_PROD((GLint)arg0[i][RCOMP] - half, 469 (GLint)arg1[i][RCOMP] - half) + 470 S_PROD((GLint)arg0[i][GCOMP] - half, 471 (GLint)arg1[i][GCOMP] - half) + 472 S_PROD((GLint)arg0[i][BCOMP] - half, 473 (GLint)arg1[i][BCOMP] - half)) >> 6; 474 dot = CLAMP(dot, 0, CHAN_MAX); 475#endif 476 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = (GLchan) dot; 477 } 478 } 479 break; 480 case GL_DOT3_RGB: 481 case GL_DOT3_RGBA: 482 { 483 /* DO scale the result by 1 2 or 4 */ 484 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 485 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 486 for (i = 0; i < n; i++) { 487#if CHAN_TYPE == GL_FLOAT 488 GLchan dot = ((arg0[i][RCOMP]-0.5F) * (arg1[i][RCOMP]-0.5F) + 489 (arg0[i][GCOMP]-0.5F) * (arg1[i][GCOMP]-0.5F) + 490 (arg0[i][BCOMP]-0.5F) * (arg1[i][BCOMP]-0.5F)) 491 * 4.0F * RGBmult; 492 dot = CLAMP(dot, 0.0, CHAN_MAXF); 493#else 494 GLint dot = (S_PROD((GLint)arg0[i][RCOMP] - half, 495 (GLint)arg1[i][RCOMP] - half) + 496 S_PROD((GLint)arg0[i][GCOMP] - half, 497 (GLint)arg1[i][GCOMP] - half) + 498 S_PROD((GLint)arg0[i][BCOMP] - half, 499 (GLint)arg1[i][BCOMP] - half)) >> 6; 500 dot <<= RGBshift; 501 dot = CLAMP(dot, 0, CHAN_MAX); 502#endif 503 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = (GLchan) dot; 504 } 505 } 506 break; 507 case GL_MODULATE_ADD_ATI: 508 { 509 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 510 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 511 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2]; 512#if CHAN_TYPE != GL_FLOAT 513 const GLint shift = CHAN_BITS - RGBshift; 514#endif 515 for (i = 0; i < n; i++) { 516#if CHAN_TYPE == GL_FLOAT 517 rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + arg1[i][RCOMP]) * RGBmult; 518 rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + arg1[i][GCOMP]) * RGBmult; 519 rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + arg1[i][BCOMP]) * RGBmult; 520#else 521 GLuint r = (PROD(arg0[i][RCOMP], arg2[i][RCOMP]) 522 + ((GLuint) arg1[i][RCOMP] << CHAN_BITS)) >> shift; 523 GLuint g = (PROD(arg0[i][GCOMP], arg2[i][GCOMP]) 524 + ((GLuint) arg1[i][GCOMP] << CHAN_BITS)) >> shift; 525 GLuint b = (PROD(arg0[i][BCOMP], arg2[i][BCOMP]) 526 + ((GLuint) arg1[i][BCOMP] << CHAN_BITS)) >> shift; 527 rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); 528 rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); 529 rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); 530#endif 531 } 532 } 533 break; 534 case GL_MODULATE_SIGNED_ADD_ATI: 535 { 536 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 537 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 538 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2]; 539#if CHAN_TYPE != GL_FLOAT 540 const GLint shift = CHAN_BITS - RGBshift; 541#endif 542 for (i = 0; i < n; i++) { 543#if CHAN_TYPE == GL_FLOAT 544 rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + arg1[i][RCOMP] - 0.5) * RGBmult; 545 rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + arg1[i][GCOMP] - 0.5) * RGBmult; 546 rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + arg1[i][BCOMP] - 0.5) * RGBmult; 547#else 548 GLint r = (S_PROD(arg0[i][RCOMP], arg2[i][RCOMP]) 549 + (((GLint) arg1[i][RCOMP] - half) << CHAN_BITS)) 550 >> shift; 551 GLint g = (S_PROD(arg0[i][GCOMP], arg2[i][GCOMP]) 552 + (((GLint) arg1[i][GCOMP] - half) << CHAN_BITS)) 553 >> shift; 554 GLint b = (S_PROD(arg0[i][BCOMP], arg2[i][BCOMP]) 555 + (((GLint) arg1[i][BCOMP] - half) << CHAN_BITS)) 556 >> shift; 557 rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); 558 rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); 559 rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); 560#endif 561 } 562 } 563 break; 564 case GL_MODULATE_SUBTRACT_ATI: 565 { 566 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; 567 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; 568 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2]; 569#if CHAN_TYPE != GL_FLOAT 570 const GLint shift = CHAN_BITS - RGBshift; 571#endif 572 for (i = 0; i < n; i++) { 573#if CHAN_TYPE == GL_FLOAT 574 rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) - arg1[i][RCOMP]) * RGBmult; 575 rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) - arg1[i][GCOMP]) * RGBmult; 576 rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) - arg1[i][BCOMP]) * RGBmult; 577#else 578 GLint r = (S_PROD(arg0[i][RCOMP], arg2[i][RCOMP]) 579 - ((GLint) arg1[i][RCOMP] << CHAN_BITS)) 580 >> shift; 581 GLint g = (S_PROD(arg0[i][GCOMP], arg2[i][GCOMP]) 582 - ((GLint) arg1[i][GCOMP] << CHAN_BITS)) 583 >> shift; 584 GLint b = (S_PROD(arg0[i][BCOMP], arg2[i][BCOMP]) 585 - ((GLint) arg1[i][BCOMP] << CHAN_BITS)) 586 >> shift; 587 rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); 588 rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); 589 rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); 590#endif 591 } 592 } 593 break; 594 default: 595 _mesa_problem(ctx, "invalid combine mode"); 596 } 597 598 switch (textureUnit->_CurrentCombine->ModeA) { 599 case GL_REPLACE: 600 { 601 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 602 if (Ashift) { 603 for (i = 0; i < n; i++) { 604#if CHAN_TYPE == GL_FLOAT 605 GLchan a = arg0[i][ACOMP] * Amult; 606#else 607 GLuint a = (GLuint) arg0[i][ACOMP] << Ashift; 608#endif 609 rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); 610 } 611 } 612 else { 613 for (i = 0; i < n; i++) { 614 rgba[i][ACOMP] = arg0[i][ACOMP]; 615 } 616 } 617 } 618 break; 619 case GL_MODULATE: 620 { 621 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 622 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 623#if CHAN_TYPE != GL_FLOAT 624 const GLint shift = CHAN_BITS - Ashift; 625#endif 626 for (i = 0; i < n; i++) { 627#if CHAN_TYPE == GL_FLOAT 628 rgba[i][ACOMP] = arg0[i][ACOMP] * arg1[i][ACOMP] * Amult; 629#else 630 GLuint a = (PROD(arg0[i][ACOMP], arg1[i][ACOMP]) >> shift); 631 rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); 632#endif 633 } 634 } 635 break; 636 case GL_ADD: 637 if (textureUnit->EnvMode == GL_COMBINE4_NV) { 638 /* (a * b) + (c * d) */ 639 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 640 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 641 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2]; 642 const GLchan (*arg3)[4] = (const GLchan (*)[4]) argA[3]; 643 for (i = 0; i < n; i++) { 644#if CHAN_TYPE == GL_FLOAT 645 rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] + 646 arg2[i][ACOMP] * arg3[i][ACOMP]) * Amult; 647#else 648 const GLint shift = CHAN_BITS - Ashift; 649 GLint a = (PROD(arg0[i][ACOMP], arg1[i][ACOMP]) >> shift) + 650 (PROD(arg2[i][ACOMP], arg3[i][ACOMP]) >> shift); 651 rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); 652#endif 653 } 654 } 655 else { 656 /* two-term add */ 657 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 658 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 659 for (i = 0; i < n; i++) { 660#if CHAN_TYPE == GL_FLOAT 661 rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP]) * Amult; 662#else 663 GLint a = ((GLint) arg0[i][ACOMP] + arg1[i][ACOMP]) << Ashift; 664 rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); 665#endif 666 } 667 } 668 break; 669 case GL_ADD_SIGNED: 670 if (textureUnit->EnvMode == GL_COMBINE4_NV) { 671 /* (a * b) + (c * d) - 0.5 */ 672 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 673 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 674 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2]; 675 const GLchan (*arg3)[4] = (const GLchan (*)[4]) argA[3]; 676 for (i = 0; i < n; i++) { 677#if CHAN_TYPE == GL_FLOAT 678 rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] + 679 arg2[i][ACOMP] * arg3[i][ACOMP] - 680 0.5) * Amult; 681#else 682 GLint a = (((PROD(arg0[i][ACOMP], arg1[i][ACOMP]) + 683 PROD(arg2[i][ACOMP], arg3[i][ACOMP])) >> CHAN_BITS) - half) 684 << Ashift; 685 rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); 686#endif 687 } 688 } 689 else { 690 /* a + b - 0.5 */ 691 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 692 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 693 for (i = 0; i < n; i++) { 694#if CHAN_TYPE == GL_FLOAT 695 rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP] - 0.5F) * Amult; 696#else 697 GLint a = (GLint) arg0[i][ACOMP] + (GLint) arg1[i][ACOMP] -half; 698 a = (a < 0) ? 0 : a << Ashift; 699 rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); 700#endif 701 } 702 } 703 break; 704 case GL_INTERPOLATE: 705 { 706 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 707 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 708 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2]; 709#if CHAN_TYPE != GL_FLOAT 710 const GLint shift = CHAN_BITS - Ashift; 711#endif 712 for (i=0; i<n; i++) { 713#if CHAN_TYPE == GL_FLOAT 714 rgba[i][ACOMP] = (arg0[i][ACOMP] * arg2[i][ACOMP] + 715 arg1[i][ACOMP] * (CHAN_MAXF - arg2[i][ACOMP])) 716 * Amult; 717#else 718 GLuint a = (PROD(arg0[i][ACOMP], arg2[i][ACOMP]) 719 + PROD(arg1[i][ACOMP], CHAN_MAX - arg2[i][ACOMP])) 720 >> shift; 721 rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); 722#endif 723 } 724 } 725 break; 726 case GL_SUBTRACT: 727 { 728 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 729 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 730 for (i = 0; i < n; i++) { 731#if CHAN_TYPE == GL_FLOAT 732 rgba[i][ACOMP] = (arg0[i][ACOMP] - arg1[i][ACOMP]) * Amult; 733#else 734 GLint a = ((GLint) arg0[i][ACOMP] - (GLint) arg1[i][ACOMP]) << Ashift; 735 rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); 736#endif 737 } 738 } 739 break; 740 case GL_MODULATE_ADD_ATI: 741 { 742 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 743 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 744 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2]; 745#if CHAN_TYPE != GL_FLOAT 746 const GLint shift = CHAN_BITS - Ashift; 747#endif 748 for (i = 0; i < n; i++) { 749#if CHAN_TYPE == GL_FLOAT 750 rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + arg1[i][ACOMP]) * Amult; 751#else 752 GLint a = (PROD(arg0[i][ACOMP], arg2[i][ACOMP]) 753 + ((GLuint) arg1[i][ACOMP] << CHAN_BITS)) 754 >> shift; 755 rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); 756#endif 757 } 758 } 759 break; 760 case GL_MODULATE_SIGNED_ADD_ATI: 761 { 762 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 763 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 764 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2]; 765#if CHAN_TYPE != GL_FLOAT 766 const GLint shift = CHAN_BITS - Ashift; 767#endif 768 for (i = 0; i < n; i++) { 769#if CHAN_TYPE == GL_FLOAT 770 rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + arg1[i][ACOMP] - 0.5F) * Amult; 771#else 772 GLint a = (S_PROD(arg0[i][ACOMP], arg2[i][ACOMP]) 773 + (((GLint) arg1[i][ACOMP] - half) << CHAN_BITS)) 774 >> shift; 775 rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); 776#endif 777 } 778 } 779 break; 780 case GL_MODULATE_SUBTRACT_ATI: 781 { 782 const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; 783 const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; 784 const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2]; 785#if CHAN_TYPE != GL_FLOAT 786 const GLint shift = CHAN_BITS - Ashift; 787#endif 788 for (i = 0; i < n; i++) { 789#if CHAN_TYPE == GL_FLOAT 790 rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) - arg1[i][ACOMP]) * Amult; 791#else 792 GLint a = (S_PROD(arg0[i][ACOMP], arg2[i][ACOMP]) 793 - ((GLint) arg1[i][ACOMP] << CHAN_BITS)) 794 >> shift; 795 rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); 796#endif 797 } 798 } 799 break; 800 default: 801 _mesa_problem(ctx, "invalid combine mode"); 802 } 803 804 /* Fix the alpha component for GL_DOT3_RGBA_EXT/ARB combining. 805 * This is kind of a kludge. It would have been better if the spec 806 * were written such that the GL_COMBINE_ALPHA value could be set to 807 * GL_DOT3. 808 */ 809 if (textureUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT || 810 textureUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) { 811 for (i = 0; i < n; i++) { 812 rgba[i][ACOMP] = rgba[i][RCOMP]; 813 } 814 } 815} 816#undef PROD 817 818 819/** 820 * Apply X/Y/Z/W/0/1 swizzle to an array of colors/texels. 821 * See GL_EXT_texture_swizzle. 822 */ 823static void 824swizzle_texels(GLuint swizzle, GLuint count, GLchan (*texels)[4]) 825{ 826 const GLuint swzR = GET_SWZ(swizzle, 0); 827 const GLuint swzG = GET_SWZ(swizzle, 1); 828 const GLuint swzB = GET_SWZ(swizzle, 2); 829 const GLuint swzA = GET_SWZ(swizzle, 3); 830 GLchan vector[6]; 831 GLuint i; 832 833 vector[SWIZZLE_ZERO] = 0; 834 vector[SWIZZLE_ONE] = CHAN_MAX; 835 836 for (i = 0; i < count; i++) { 837 vector[SWIZZLE_X] = texels[i][0]; 838 vector[SWIZZLE_Y] = texels[i][1]; 839 vector[SWIZZLE_Z] = texels[i][2]; 840 vector[SWIZZLE_W] = texels[i][3]; 841 texels[i][RCOMP] = vector[swzR]; 842 texels[i][GCOMP] = vector[swzG]; 843 texels[i][BCOMP] = vector[swzB]; 844 texels[i][ACOMP] = vector[swzA]; 845 } 846} 847 848 849/** 850 * Apply a conventional OpenGL texture env mode (REPLACE, ADD, BLEND, 851 * MODULATE, or DECAL) to an array of fragments. 852 * Input: textureUnit - pointer to texture unit to apply 853 * format - base internal texture format 854 * n - number of fragments 855 * primary_rgba - primary colors (may alias rgba for single texture) 856 * texels - array of texel colors 857 * InOut: rgba - incoming fragment colors modified by texel colors 858 * according to the texture environment mode. 859 */ 860static void 861texture_apply( const GLcontext *ctx, 862 const struct gl_texture_unit *texUnit, 863 GLuint n, 864 CONST GLchan primary_rgba[][4], CONST GLchan texel[][4], 865 GLchan rgba[][4] ) 866{ 867 GLint baseLevel; 868 GLuint i; 869 GLchan Rc, Gc, Bc, Ac; 870 GLenum format; 871 (void) primary_rgba; 872 873 ASSERT(texUnit); 874 ASSERT(texUnit->_Current); 875 876 baseLevel = texUnit->_Current->BaseLevel; 877 ASSERT(texUnit->_Current->Image[0][baseLevel]); 878 879 format = texUnit->_Current->Image[0][baseLevel]->_BaseFormat; 880 881 if (format == GL_COLOR_INDEX || format == GL_YCBCR_MESA) { 882 format = GL_RGBA; /* a bit of a hack */ 883 } 884 else if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) { 885 format = texUnit->_Current->DepthMode; 886 } 887 888 switch (texUnit->EnvMode) { 889 case GL_REPLACE: 890 switch (format) { 891 case GL_ALPHA: 892 for (i=0;i<n;i++) { 893 /* Cv = Cf */ 894 /* Av = At */ 895 rgba[i][ACOMP] = texel[i][ACOMP]; 896 } 897 break; 898 case GL_LUMINANCE: 899 for (i=0;i<n;i++) { 900 /* Cv = Lt */ 901 GLchan Lt = texel[i][RCOMP]; 902 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt; 903 /* Av = Af */ 904 } 905 break; 906 case GL_LUMINANCE_ALPHA: 907 for (i=0;i<n;i++) { 908 GLchan Lt = texel[i][RCOMP]; 909 /* Cv = Lt */ 910 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt; 911 /* Av = At */ 912 rgba[i][ACOMP] = texel[i][ACOMP]; 913 } 914 break; 915 case GL_INTENSITY: 916 for (i=0;i<n;i++) { 917 /* Cv = It */ 918 GLchan It = texel[i][RCOMP]; 919 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = It; 920 /* Av = It */ 921 rgba[i][ACOMP] = It; 922 } 923 break; 924 case GL_RGB: 925 for (i=0;i<n;i++) { 926 /* Cv = Ct */ 927 rgba[i][RCOMP] = texel[i][RCOMP]; 928 rgba[i][GCOMP] = texel[i][GCOMP]; 929 rgba[i][BCOMP] = texel[i][BCOMP]; 930 /* Av = Af */ 931 } 932 break; 933 case GL_RGBA: 934 for (i=0;i<n;i++) { 935 /* Cv = Ct */ 936 rgba[i][RCOMP] = texel[i][RCOMP]; 937 rgba[i][GCOMP] = texel[i][GCOMP]; 938 rgba[i][BCOMP] = texel[i][BCOMP]; 939 /* Av = At */ 940 rgba[i][ACOMP] = texel[i][ACOMP]; 941 } 942 break; 943 default: 944 _mesa_problem(ctx, "Bad format (GL_REPLACE) in texture_apply"); 945 return; 946 } 947 break; 948 949 case GL_MODULATE: 950 switch (format) { 951 case GL_ALPHA: 952 for (i=0;i<n;i++) { 953 /* Cv = Cf */ 954 /* Av = AfAt */ 955 rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] ); 956 } 957 break; 958 case GL_LUMINANCE: 959 for (i=0;i<n;i++) { 960 /* Cv = LtCf */ 961 GLchan Lt = texel[i][RCOMP]; 962 rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], Lt ); 963 rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], Lt ); 964 rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], Lt ); 965 /* Av = Af */ 966 } 967 break; 968 case GL_LUMINANCE_ALPHA: 969 for (i=0;i<n;i++) { 970 /* Cv = CfLt */ 971 GLchan Lt = texel[i][RCOMP]; 972 rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], Lt ); 973 rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], Lt ); 974 rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], Lt ); 975 /* Av = AfAt */ 976 rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] ); 977 } 978 break; 979 case GL_INTENSITY: 980 for (i=0;i<n;i++) { 981 /* Cv = CfIt */ 982 GLchan It = texel[i][RCOMP]; 983 rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], It ); 984 rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], It ); 985 rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], It ); 986 /* Av = AfIt */ 987 rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], It ); 988 } 989 break; 990 case GL_RGB: 991 for (i=0;i<n;i++) { 992 /* Cv = CfCt */ 993 rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], texel[i][RCOMP] ); 994 rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], texel[i][GCOMP] ); 995 rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], texel[i][BCOMP] ); 996 /* Av = Af */ 997 } 998 break; 999 case GL_RGBA: 1000 for (i=0;i<n;i++) { 1001 /* Cv = CfCt */ 1002 rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], texel[i][RCOMP] ); 1003 rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], texel[i][GCOMP] ); 1004 rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], texel[i][BCOMP] ); 1005 /* Av = AfAt */ 1006 rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] ); 1007 } 1008 break; 1009 default: 1010 _mesa_problem(ctx, "Bad format (GL_MODULATE) in texture_apply"); 1011 return; 1012 } 1013 break; 1014 1015 case GL_DECAL: 1016 switch (format) { 1017 case GL_ALPHA: 1018 case GL_LUMINANCE: 1019 case GL_LUMINANCE_ALPHA: 1020 case GL_INTENSITY: 1021 /* undefined */ 1022 break; 1023 case GL_RGB: 1024 for (i=0;i<n;i++) { 1025 /* Cv = Ct */ 1026 rgba[i][RCOMP] = texel[i][RCOMP]; 1027 rgba[i][GCOMP] = texel[i][GCOMP]; 1028 rgba[i][BCOMP] = texel[i][BCOMP]; 1029 /* Av = Af */ 1030 } 1031 break; 1032 case GL_RGBA: 1033 for (i=0;i<n;i++) { 1034 /* Cv = Cf(1-At) + CtAt */ 1035 GLchan t = texel[i][ACOMP], s = CHAN_MAX - t; 1036 rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(texel[i][RCOMP],t); 1037 rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(texel[i][GCOMP],t); 1038 rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(texel[i][BCOMP],t); 1039 /* Av = Af */ 1040 } 1041 break; 1042 default: 1043 _mesa_problem(ctx, "Bad format (GL_DECAL) in texture_apply"); 1044 return; 1045 } 1046 break; 1047 1048 case GL_BLEND: 1049 UNCLAMPED_FLOAT_TO_CHAN(Rc, texUnit->EnvColor[0]); 1050 UNCLAMPED_FLOAT_TO_CHAN(Gc, texUnit->EnvColor[1]); 1051 UNCLAMPED_FLOAT_TO_CHAN(Bc, texUnit->EnvColor[2]); 1052 UNCLAMPED_FLOAT_TO_CHAN(Ac, texUnit->EnvColor[3]); 1053 switch (format) { 1054 case GL_ALPHA: 1055 for (i=0;i<n;i++) { 1056 /* Cv = Cf */ 1057 /* Av = AfAt */ 1058 rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]); 1059 } 1060 break; 1061 case GL_LUMINANCE: 1062 for (i=0;i<n;i++) { 1063 /* Cv = Cf(1-Lt) + CcLt */ 1064 GLchan Lt = texel[i][RCOMP], s = CHAN_MAX - Lt; 1065 rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, Lt); 1066 rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, Lt); 1067 rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, Lt); 1068 /* Av = Af */ 1069 } 1070 break; 1071 case GL_LUMINANCE_ALPHA: 1072 for (i=0;i<n;i++) { 1073 /* Cv = Cf(1-Lt) + CcLt */ 1074 GLchan Lt = texel[i][RCOMP], s = CHAN_MAX - Lt; 1075 rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, Lt); 1076 rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, Lt); 1077 rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, Lt); 1078 /* Av = AfAt */ 1079 rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP],texel[i][ACOMP]); 1080 } 1081 break; 1082 case GL_INTENSITY: 1083 for (i=0;i<n;i++) { 1084 /* Cv = Cf(1-It) + CcIt */ 1085 GLchan It = texel[i][RCOMP], s = CHAN_MAX - It; 1086 rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, It); 1087 rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, It); 1088 rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, It); 1089 /* Av = Af(1-It) + Ac*It */ 1090 rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], s) + CHAN_PRODUCT(Ac, It); 1091 } 1092 break; 1093 case GL_RGB: 1094 for (i=0;i<n;i++) { 1095 /* Cv = Cf(1-Ct) + CcCt */ 1096 rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], (CHAN_MAX-texel[i][RCOMP])) + CHAN_PRODUCT(Rc,texel[i][RCOMP]); 1097 rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], (CHAN_MAX-texel[i][GCOMP])) + CHAN_PRODUCT(Gc,texel[i][GCOMP]); 1098 rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], (CHAN_MAX-texel[i][BCOMP])) + CHAN_PRODUCT(Bc,texel[i][BCOMP]); 1099 /* Av = Af */ 1100 } 1101 break; 1102 case GL_RGBA: 1103 for (i=0;i<n;i++) { 1104 /* Cv = Cf(1-Ct) + CcCt */ 1105 rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], (CHAN_MAX-texel[i][RCOMP])) + CHAN_PRODUCT(Rc,texel[i][RCOMP]); 1106 rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], (CHAN_MAX-texel[i][GCOMP])) + CHAN_PRODUCT(Gc,texel[i][GCOMP]); 1107 rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], (CHAN_MAX-texel[i][BCOMP])) + CHAN_PRODUCT(Bc,texel[i][BCOMP]); 1108 /* Av = AfAt */ 1109 rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP],texel[i][ACOMP]); 1110 } 1111 break; 1112 default: 1113 _mesa_problem(ctx, "Bad format (GL_BLEND) in texture_apply"); 1114 return; 1115 } 1116 break; 1117 1118 /* XXX don't clamp results if GLchan is float??? */ 1119 1120 case GL_ADD: /* GL_EXT_texture_add_env */ 1121 switch (format) { 1122 case GL_ALPHA: 1123 for (i=0;i<n;i++) { 1124 /* Rv = Rf */ 1125 /* Gv = Gf */ 1126 /* Bv = Bf */ 1127 rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]); 1128 } 1129 break; 1130 case GL_LUMINANCE: 1131 for (i=0;i<n;i++) { 1132 ChanTemp Lt = texel[i][RCOMP]; 1133 ChanTemp r = rgba[i][RCOMP] + Lt; 1134 ChanTemp g = rgba[i][GCOMP] + Lt; 1135 ChanTemp b = rgba[i][BCOMP] + Lt; 1136 rgba[i][RCOMP] = MIN2(r, CHAN_MAX); 1137 rgba[i][GCOMP] = MIN2(g, CHAN_MAX); 1138 rgba[i][BCOMP] = MIN2(b, CHAN_MAX); 1139 /* Av = Af */ 1140 } 1141 break; 1142 case GL_LUMINANCE_ALPHA: 1143 for (i=0;i<n;i++) { 1144 ChanTemp Lt = texel[i][RCOMP]; 1145 ChanTemp r = rgba[i][RCOMP] + Lt; 1146 ChanTemp g = rgba[i][GCOMP] + Lt; 1147 ChanTemp b = rgba[i][BCOMP] + Lt; 1148 rgba[i][RCOMP] = MIN2(r, CHAN_MAX); 1149 rgba[i][GCOMP] = MIN2(g, CHAN_MAX); 1150 rgba[i][BCOMP] = MIN2(b, CHAN_MAX); 1151 rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]); 1152 } 1153 break; 1154 case GL_INTENSITY: 1155 for (i=0;i<n;i++) { 1156 GLchan It = texel[i][RCOMP]; 1157 ChanTemp r = rgba[i][RCOMP] + It; 1158 ChanTemp g = rgba[i][GCOMP] + It; 1159 ChanTemp b = rgba[i][BCOMP] + It; 1160 ChanTemp a = rgba[i][ACOMP] + It; 1161 rgba[i][RCOMP] = MIN2(r, CHAN_MAX); 1162 rgba[i][GCOMP] = MIN2(g, CHAN_MAX); 1163 rgba[i][BCOMP] = MIN2(b, CHAN_MAX); 1164 rgba[i][ACOMP] = MIN2(a, CHAN_MAX); 1165 } 1166 break; 1167 case GL_RGB: 1168 for (i=0;i<n;i++) { 1169 ChanTemp r = rgba[i][RCOMP] + texel[i][RCOMP]; 1170 ChanTemp g = rgba[i][GCOMP] + texel[i][GCOMP]; 1171 ChanTemp b = rgba[i][BCOMP] + texel[i][BCOMP]; 1172 rgba[i][RCOMP] = MIN2(r, CHAN_MAX); 1173 rgba[i][GCOMP] = MIN2(g, CHAN_MAX); 1174 rgba[i][BCOMP] = MIN2(b, CHAN_MAX); 1175 /* Av = Af */ 1176 } 1177 break; 1178 case GL_RGBA: 1179 for (i=0;i<n;i++) { 1180 ChanTemp r = rgba[i][RCOMP] + texel[i][RCOMP]; 1181 ChanTemp g = rgba[i][GCOMP] + texel[i][GCOMP]; 1182 ChanTemp b = rgba[i][BCOMP] + texel[i][BCOMP]; 1183 rgba[i][RCOMP] = MIN2(r, CHAN_MAX); 1184 rgba[i][GCOMP] = MIN2(g, CHAN_MAX); 1185 rgba[i][BCOMP] = MIN2(b, CHAN_MAX); 1186 rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]); 1187 } 1188 break; 1189 default: 1190 _mesa_problem(ctx, "Bad format (GL_ADD) in texture_apply"); 1191 return; 1192 } 1193 break; 1194 1195 default: 1196 _mesa_problem(ctx, "Bad env mode in texture_apply"); 1197 return; 1198 } 1199} 1200 1201 1202 1203/** 1204 * Apply texture mapping to a span of fragments. 1205 */ 1206void 1207_swrast_texture_span( GLcontext *ctx, SWspan *span ) 1208{ 1209 SWcontext *swrast = SWRAST_CONTEXT(ctx); 1210 GLchan primary_rgba[MAX_WIDTH][4]; 1211 GLuint unit; 1212 1213 ASSERT(span->end < MAX_WIDTH); 1214 1215 /* 1216 * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR) 1217 */ 1218 if (swrast->_AnyTextureCombine) 1219 MEMCPY(primary_rgba, span->array->rgba, 4 * span->end * sizeof(GLchan)); 1220 1221 /* 1222 * Must do all texture sampling before combining in order to 1223 * accomodate GL_ARB_texture_env_crossbar. 1224 */ 1225 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { 1226 if (ctx->Texture.Unit[unit]._ReallyEnabled) { 1227 const GLfloat (*texcoords)[4] 1228 = (const GLfloat (*)[4]) 1229 span->array->attribs[FRAG_ATTRIB_TEX0 + unit]; 1230 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1231 const struct gl_texture_object *curObj = texUnit->_Current; 1232 GLfloat *lambda = span->array->lambda[unit]; 1233 GLchan (*texels)[4] = (GLchan (*)[4]) 1234 (swrast->TexelBuffer + unit * (span->end * 4 * sizeof(GLchan))); 1235 1236 /* adjust texture lod (lambda) */ 1237 if (span->arrayMask & SPAN_LAMBDA) { 1238 if (texUnit->LodBias + curObj->LodBias != 0.0F) { 1239 /* apply LOD bias, but don't clamp yet */ 1240 const GLfloat bias = CLAMP(texUnit->LodBias + curObj->LodBias, 1241 -ctx->Const.MaxTextureLodBias, 1242 ctx->Const.MaxTextureLodBias); 1243 GLuint i; 1244 for (i = 0; i < span->end; i++) { 1245 lambda[i] += bias; 1246 } 1247 } 1248 1249 if (curObj->MinLod != -1000.0 || curObj->MaxLod != 1000.0) { 1250 /* apply LOD clamping to lambda */ 1251 const GLfloat min = curObj->MinLod; 1252 const GLfloat max = curObj->MaxLod; 1253 GLuint i; 1254 for (i = 0; i < span->end; i++) { 1255 GLfloat l = lambda[i]; 1256 lambda[i] = CLAMP(l, min, max); 1257 } 1258 } 1259 } 1260 1261 /* Sample the texture (span->end = number of fragments) */ 1262 swrast->TextureSample[unit]( ctx, texUnit->_Current, span->end, 1263 texcoords, lambda, texels ); 1264 1265 /* GL_SGI_texture_color_table */ 1266 if (texUnit->ColorTableEnabled) { 1267#if CHAN_TYPE == GL_UNSIGNED_BYTE 1268 _mesa_lookup_rgba_ubyte(&texUnit->ColorTable, span->end, texels); 1269#elif CHAN_TYPE == GL_UNSIGNED_SHORT 1270 _mesa_lookup_rgba_ubyte(&texUnit->ColorTable, span->end, texels); 1271#else 1272 _mesa_lookup_rgba_float(&texUnit->ColorTable, span->end, texels); 1273#endif 1274 } 1275 1276 /* GL_EXT_texture_swizzle */ 1277 if (curObj->_Swizzle != SWIZZLE_NOOP) { 1278 swizzle_texels(curObj->_Swizzle, span->end, texels); 1279 } 1280 } 1281 } 1282 1283 1284 /* 1285 * OK, now apply the texture (aka texture combine/blend). 1286 * We modify the span->color.rgba values. 1287 */ 1288 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { 1289 if (ctx->Texture.Unit[unit]._ReallyEnabled) { 1290 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1291 if (texUnit->_CurrentCombine != &texUnit->_EnvMode ) { 1292 texture_combine( ctx, unit, span->end, 1293 (CONST GLchan (*)[4]) primary_rgba, 1294 swrast->TexelBuffer, 1295 span->array->rgba ); 1296 } 1297 else { 1298 /* conventional texture blend */ 1299 const GLchan (*texels)[4] = (const GLchan (*)[4]) 1300 (swrast->TexelBuffer + unit * 1301 (span->end * 4 * sizeof(GLchan))); 1302 1303 1304 texture_apply( ctx, texUnit, span->end, 1305 (CONST GLchan (*)[4]) primary_rgba, texels, 1306 span->array->rgba ); 1307 } 1308 } 1309 } 1310} 1311