prog_statevars.c revision af69d88d
1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25/** 26 * \file prog_statevars.c 27 * Program state variable management. 28 * \author Brian Paul 29 */ 30 31 32#include "main/glheader.h" 33#include "main/context.h" 34#include "main/blend.h" 35#include "main/imports.h" 36#include "main/macros.h" 37#include "main/mtypes.h" 38#include "main/fbobject.h" 39#include "prog_statevars.h" 40#include "prog_parameter.h" 41#include "main/samplerobj.h" 42 43 44/** 45 * Use the list of tokens in the state[] array to find global GL state 46 * and return it in <value>. Usually, four values are returned in <value> 47 * but matrix queries may return as many as 16 values. 48 * This function is used for ARB vertex/fragment programs. 49 * The program parser will produce the state[] values. 50 */ 51static void 52_mesa_fetch_state(struct gl_context *ctx, const gl_state_index state[], 53 GLfloat *value) 54{ 55 switch (state[0]) { 56 case STATE_MATERIAL: 57 { 58 /* state[1] is either 0=front or 1=back side */ 59 const GLuint face = (GLuint) state[1]; 60 const struct gl_material *mat = &ctx->Light.Material; 61 ASSERT(face == 0 || face == 1); 62 /* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */ 63 ASSERT(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT); 64 /* XXX we could get rid of this switch entirely with a little 65 * work in arbprogparse.c's parse_state_single_item(). 66 */ 67 /* state[2] is the material attribute */ 68 switch (state[2]) { 69 case STATE_AMBIENT: 70 COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]); 71 return; 72 case STATE_DIFFUSE: 73 COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]); 74 return; 75 case STATE_SPECULAR: 76 COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]); 77 return; 78 case STATE_EMISSION: 79 COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]); 80 return; 81 case STATE_SHININESS: 82 value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0]; 83 value[1] = 0.0F; 84 value[2] = 0.0F; 85 value[3] = 1.0F; 86 return; 87 default: 88 _mesa_problem(ctx, "Invalid material state in fetch_state"); 89 return; 90 } 91 } 92 case STATE_LIGHT: 93 { 94 /* state[1] is the light number */ 95 const GLuint ln = (GLuint) state[1]; 96 /* state[2] is the light attribute */ 97 switch (state[2]) { 98 case STATE_AMBIENT: 99 COPY_4V(value, ctx->Light.Light[ln].Ambient); 100 return; 101 case STATE_DIFFUSE: 102 COPY_4V(value, ctx->Light.Light[ln].Diffuse); 103 return; 104 case STATE_SPECULAR: 105 COPY_4V(value, ctx->Light.Light[ln].Specular); 106 return; 107 case STATE_POSITION: 108 COPY_4V(value, ctx->Light.Light[ln].EyePosition); 109 return; 110 case STATE_ATTENUATION: 111 value[0] = ctx->Light.Light[ln].ConstantAttenuation; 112 value[1] = ctx->Light.Light[ln].LinearAttenuation; 113 value[2] = ctx->Light.Light[ln].QuadraticAttenuation; 114 value[3] = ctx->Light.Light[ln].SpotExponent; 115 return; 116 case STATE_SPOT_DIRECTION: 117 COPY_3V(value, ctx->Light.Light[ln].SpotDirection); 118 value[3] = ctx->Light.Light[ln]._CosCutoff; 119 return; 120 case STATE_SPOT_CUTOFF: 121 value[0] = ctx->Light.Light[ln].SpotCutoff; 122 return; 123 case STATE_HALF_VECTOR: 124 { 125 static const GLfloat eye_z[] = {0, 0, 1}; 126 GLfloat p[3]; 127 /* Compute infinite half angle vector: 128 * halfVector = normalize(normalize(lightPos) + (0, 0, 1)) 129 * light.EyePosition.w should be 0 for infinite lights. 130 */ 131 COPY_3V(p, ctx->Light.Light[ln].EyePosition); 132 NORMALIZE_3FV(p); 133 ADD_3V(value, p, eye_z); 134 NORMALIZE_3FV(value); 135 value[3] = 1.0; 136 } 137 return; 138 default: 139 _mesa_problem(ctx, "Invalid light state in fetch_state"); 140 return; 141 } 142 } 143 case STATE_LIGHTMODEL_AMBIENT: 144 COPY_4V(value, ctx->Light.Model.Ambient); 145 return; 146 case STATE_LIGHTMODEL_SCENECOLOR: 147 if (state[1] == 0) { 148 /* front */ 149 GLint i; 150 for (i = 0; i < 3; i++) { 151 value[i] = ctx->Light.Model.Ambient[i] 152 * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i] 153 + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i]; 154 } 155 value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; 156 } 157 else { 158 /* back */ 159 GLint i; 160 for (i = 0; i < 3; i++) { 161 value[i] = ctx->Light.Model.Ambient[i] 162 * ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i] 163 + ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i]; 164 } 165 value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; 166 } 167 return; 168 case STATE_LIGHTPROD: 169 { 170 const GLuint ln = (GLuint) state[1]; 171 const GLuint face = (GLuint) state[2]; 172 GLint i; 173 ASSERT(face == 0 || face == 1); 174 switch (state[3]) { 175 case STATE_AMBIENT: 176 for (i = 0; i < 3; i++) { 177 value[i] = ctx->Light.Light[ln].Ambient[i] * 178 ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i]; 179 } 180 /* [3] = material alpha */ 181 value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][3]; 182 return; 183 case STATE_DIFFUSE: 184 for (i = 0; i < 3; i++) { 185 value[i] = ctx->Light.Light[ln].Diffuse[i] * 186 ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][i]; 187 } 188 /* [3] = material alpha */ 189 value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; 190 return; 191 case STATE_SPECULAR: 192 for (i = 0; i < 3; i++) { 193 value[i] = ctx->Light.Light[ln].Specular[i] * 194 ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i]; 195 } 196 /* [3] = material alpha */ 197 value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][3]; 198 return; 199 default: 200 _mesa_problem(ctx, "Invalid lightprod state in fetch_state"); 201 return; 202 } 203 } 204 case STATE_TEXGEN: 205 { 206 /* state[1] is the texture unit */ 207 const GLuint unit = (GLuint) state[1]; 208 /* state[2] is the texgen attribute */ 209 switch (state[2]) { 210 case STATE_TEXGEN_EYE_S: 211 COPY_4V(value, ctx->Texture.Unit[unit].GenS.EyePlane); 212 return; 213 case STATE_TEXGEN_EYE_T: 214 COPY_4V(value, ctx->Texture.Unit[unit].GenT.EyePlane); 215 return; 216 case STATE_TEXGEN_EYE_R: 217 COPY_4V(value, ctx->Texture.Unit[unit].GenR.EyePlane); 218 return; 219 case STATE_TEXGEN_EYE_Q: 220 COPY_4V(value, ctx->Texture.Unit[unit].GenQ.EyePlane); 221 return; 222 case STATE_TEXGEN_OBJECT_S: 223 COPY_4V(value, ctx->Texture.Unit[unit].GenS.ObjectPlane); 224 return; 225 case STATE_TEXGEN_OBJECT_T: 226 COPY_4V(value, ctx->Texture.Unit[unit].GenT.ObjectPlane); 227 return; 228 case STATE_TEXGEN_OBJECT_R: 229 COPY_4V(value, ctx->Texture.Unit[unit].GenR.ObjectPlane); 230 return; 231 case STATE_TEXGEN_OBJECT_Q: 232 COPY_4V(value, ctx->Texture.Unit[unit].GenQ.ObjectPlane); 233 return; 234 default: 235 _mesa_problem(ctx, "Invalid texgen state in fetch_state"); 236 return; 237 } 238 } 239 case STATE_TEXENV_COLOR: 240 { 241 /* state[1] is the texture unit */ 242 const GLuint unit = (GLuint) state[1]; 243 if (_mesa_get_clamp_fragment_color(ctx)) 244 COPY_4V(value, ctx->Texture.Unit[unit].EnvColor); 245 else 246 COPY_4V(value, ctx->Texture.Unit[unit].EnvColorUnclamped); 247 } 248 return; 249 case STATE_FOG_COLOR: 250 if (_mesa_get_clamp_fragment_color(ctx)) 251 COPY_4V(value, ctx->Fog.Color); 252 else 253 COPY_4V(value, ctx->Fog.ColorUnclamped); 254 return; 255 case STATE_FOG_PARAMS: 256 value[0] = ctx->Fog.Density; 257 value[1] = ctx->Fog.Start; 258 value[2] = ctx->Fog.End; 259 value[3] = 1.0f / (ctx->Fog.End - ctx->Fog.Start); 260 return; 261 case STATE_CLIPPLANE: 262 { 263 const GLuint plane = (GLuint) state[1]; 264 COPY_4V(value, ctx->Transform.EyeUserPlane[plane]); 265 } 266 return; 267 case STATE_POINT_SIZE: 268 value[0] = ctx->Point.Size; 269 value[1] = ctx->Point.MinSize; 270 value[2] = ctx->Point.MaxSize; 271 value[3] = ctx->Point.Threshold; 272 return; 273 case STATE_POINT_ATTENUATION: 274 value[0] = ctx->Point.Params[0]; 275 value[1] = ctx->Point.Params[1]; 276 value[2] = ctx->Point.Params[2]; 277 value[3] = 1.0F; 278 return; 279 case STATE_MODELVIEW_MATRIX: 280 case STATE_PROJECTION_MATRIX: 281 case STATE_MVP_MATRIX: 282 case STATE_TEXTURE_MATRIX: 283 case STATE_PROGRAM_MATRIX: 284 { 285 /* state[0] = modelview, projection, texture, etc. */ 286 /* state[1] = which texture matrix or program matrix */ 287 /* state[2] = first row to fetch */ 288 /* state[3] = last row to fetch */ 289 /* state[4] = transpose, inverse or invtrans */ 290 const GLmatrix *matrix; 291 const gl_state_index mat = state[0]; 292 const GLuint index = (GLuint) state[1]; 293 const GLuint firstRow = (GLuint) state[2]; 294 const GLuint lastRow = (GLuint) state[3]; 295 const gl_state_index modifier = state[4]; 296 const GLfloat *m; 297 GLuint row, i; 298 ASSERT(firstRow >= 0); 299 ASSERT(firstRow < 4); 300 ASSERT(lastRow >= 0); 301 ASSERT(lastRow < 4); 302 if (mat == STATE_MODELVIEW_MATRIX) { 303 matrix = ctx->ModelviewMatrixStack.Top; 304 } 305 else if (mat == STATE_PROJECTION_MATRIX) { 306 matrix = ctx->ProjectionMatrixStack.Top; 307 } 308 else if (mat == STATE_MVP_MATRIX) { 309 matrix = &ctx->_ModelProjectMatrix; 310 } 311 else if (mat == STATE_TEXTURE_MATRIX) { 312 ASSERT(index < Elements(ctx->TextureMatrixStack)); 313 matrix = ctx->TextureMatrixStack[index].Top; 314 } 315 else if (mat == STATE_PROGRAM_MATRIX) { 316 ASSERT(index < Elements(ctx->ProgramMatrixStack)); 317 matrix = ctx->ProgramMatrixStack[index].Top; 318 } 319 else { 320 _mesa_problem(ctx, "Bad matrix name in _mesa_fetch_state()"); 321 return; 322 } 323 if (modifier == STATE_MATRIX_INVERSE || 324 modifier == STATE_MATRIX_INVTRANS) { 325 /* Be sure inverse is up to date: 326 */ 327 _math_matrix_analyse( (GLmatrix*) matrix ); 328 m = matrix->inv; 329 } 330 else { 331 m = matrix->m; 332 } 333 if (modifier == STATE_MATRIX_TRANSPOSE || 334 modifier == STATE_MATRIX_INVTRANS) { 335 for (i = 0, row = firstRow; row <= lastRow; row++) { 336 value[i++] = m[row * 4 + 0]; 337 value[i++] = m[row * 4 + 1]; 338 value[i++] = m[row * 4 + 2]; 339 value[i++] = m[row * 4 + 3]; 340 } 341 } 342 else { 343 for (i = 0, row = firstRow; row <= lastRow; row++) { 344 value[i++] = m[row + 0]; 345 value[i++] = m[row + 4]; 346 value[i++] = m[row + 8]; 347 value[i++] = m[row + 12]; 348 } 349 } 350 } 351 return; 352 case STATE_NUM_SAMPLES: 353 ((int *)value)[0] = ctx->DrawBuffer->Visual.samples; 354 return; 355 case STATE_DEPTH_RANGE: 356 value[0] = ctx->ViewportArray[0].Near; /* near */ 357 value[1] = ctx->ViewportArray[0].Far; /* far */ 358 value[2] = ctx->ViewportArray[0].Far - ctx->ViewportArray[0].Near; /* far - near */ 359 value[3] = 1.0; 360 return; 361 case STATE_FRAGMENT_PROGRAM: 362 { 363 /* state[1] = {STATE_ENV, STATE_LOCAL} */ 364 /* state[2] = parameter index */ 365 const int idx = (int) state[2]; 366 switch (state[1]) { 367 case STATE_ENV: 368 COPY_4V(value, ctx->FragmentProgram.Parameters[idx]); 369 return; 370 case STATE_LOCAL: 371 if (!ctx->FragmentProgram.Current->Base.LocalParams) { 372 ctx->FragmentProgram.Current->Base.LocalParams = 373 calloc(MAX_PROGRAM_LOCAL_PARAMS, sizeof(float[4])); 374 if (!ctx->FragmentProgram.Current->Base.LocalParams) 375 return; 376 } 377 378 COPY_4V(value, ctx->FragmentProgram.Current->Base.LocalParams[idx]); 379 return; 380 default: 381 _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()"); 382 return; 383 } 384 } 385 return; 386 387 case STATE_VERTEX_PROGRAM: 388 { 389 /* state[1] = {STATE_ENV, STATE_LOCAL} */ 390 /* state[2] = parameter index */ 391 const int idx = (int) state[2]; 392 switch (state[1]) { 393 case STATE_ENV: 394 COPY_4V(value, ctx->VertexProgram.Parameters[idx]); 395 return; 396 case STATE_LOCAL: 397 if (!ctx->VertexProgram.Current->Base.LocalParams) { 398 ctx->VertexProgram.Current->Base.LocalParams = 399 calloc(MAX_PROGRAM_LOCAL_PARAMS, sizeof(float[4])); 400 if (!ctx->VertexProgram.Current->Base.LocalParams) 401 return; 402 } 403 404 COPY_4V(value, ctx->VertexProgram.Current->Base.LocalParams[idx]); 405 return; 406 default: 407 _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()"); 408 return; 409 } 410 } 411 return; 412 413 case STATE_NORMAL_SCALE: 414 ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1); 415 return; 416 417 case STATE_INTERNAL: 418 switch (state[1]) { 419 case STATE_CURRENT_ATTRIB: 420 { 421 const GLuint idx = (GLuint) state[2]; 422 COPY_4V(value, ctx->Current.Attrib[idx]); 423 } 424 return; 425 426 case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED: 427 { 428 const GLuint idx = (GLuint) state[2]; 429 if(ctx->Light._ClampVertexColor && 430 (idx == VERT_ATTRIB_COLOR0 || 431 idx == VERT_ATTRIB_COLOR1)) { 432 value[0] = CLAMP(ctx->Current.Attrib[idx][0], 0.0f, 1.0f); 433 value[1] = CLAMP(ctx->Current.Attrib[idx][1], 0.0f, 1.0f); 434 value[2] = CLAMP(ctx->Current.Attrib[idx][2], 0.0f, 1.0f); 435 value[3] = CLAMP(ctx->Current.Attrib[idx][3], 0.0f, 1.0f); 436 } 437 else 438 COPY_4V(value, ctx->Current.Attrib[idx]); 439 } 440 return; 441 442 case STATE_NORMAL_SCALE: 443 ASSIGN_4V(value, 444 ctx->_ModelViewInvScale, 445 ctx->_ModelViewInvScale, 446 ctx->_ModelViewInvScale, 447 1); 448 return; 449 450 case STATE_TEXRECT_SCALE: 451 /* Value = { 1/texWidth, 1/texHeight, 0, 1 }. 452 * Used to convert unnormalized texcoords to normalized texcoords. 453 */ 454 { 455 const int unit = (int) state[2]; 456 const struct gl_texture_object *texObj 457 = ctx->Texture.Unit[unit]._Current; 458 if (texObj) { 459 struct gl_texture_image *texImage = texObj->Image[0][0]; 460 ASSIGN_4V(value, 461 (GLfloat) (1.0 / texImage->Width), 462 (GLfloat) (1.0 / texImage->Height), 463 0.0f, 1.0f); 464 } 465 } 466 return; 467 468 case STATE_FOG_PARAMS_OPTIMIZED: 469 /* for simpler per-vertex/pixel fog calcs. POW (for EXP/EXP2 fog) 470 * might be more expensive than EX2 on some hw, plus it needs 471 * another constant (e) anyway. Linear fog can now be done with a 472 * single MAD. 473 * linear: fogcoord * -1/(end-start) + end/(end-start) 474 * exp: 2^-(density/ln(2) * fogcoord) 475 * exp2: 2^-((density/(ln(2)^2) * fogcoord)^2) 476 */ 477 value[0] = (ctx->Fog.End == ctx->Fog.Start) 478 ? 1.0f : (GLfloat)(-1.0F / (ctx->Fog.End - ctx->Fog.Start)); 479 value[1] = ctx->Fog.End * -value[0]; 480 value[2] = (GLfloat)(ctx->Fog.Density * M_LOG2E); /* M_LOG2E == 1/ln(2) */ 481 value[3] = (GLfloat)(ctx->Fog.Density * ONE_DIV_SQRT_LN2); 482 return; 483 484 case STATE_POINT_SIZE_CLAMPED: 485 { 486 /* this includes implementation dependent limits, to avoid 487 * another potentially necessary clamp. 488 * Note: for sprites, point smooth (point AA) is ignored 489 * and we'll clamp to MinPointSizeAA and MaxPointSize, because we 490 * expect drivers will want to say their minimum for AA size is 0.0 491 * but for non-AA it's 1.0 (because normal points with size below 1.0 492 * need to get rounded up to 1.0, hence never disappear). GL does 493 * not specify max clamp size for sprites, other than it needs to be 494 * at least as large as max AA size, hence use non-AA size there. 495 */ 496 GLfloat minImplSize; 497 GLfloat maxImplSize; 498 if (ctx->Point.PointSprite) { 499 minImplSize = ctx->Const.MinPointSizeAA; 500 maxImplSize = ctx->Const.MaxPointSize; 501 } 502 else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) { 503 minImplSize = ctx->Const.MinPointSizeAA; 504 maxImplSize = ctx->Const.MaxPointSizeAA; 505 } 506 else { 507 minImplSize = ctx->Const.MinPointSize; 508 maxImplSize = ctx->Const.MaxPointSize; 509 } 510 value[0] = ctx->Point.Size; 511 value[1] = ctx->Point.MinSize >= minImplSize ? ctx->Point.MinSize : minImplSize; 512 value[2] = ctx->Point.MaxSize <= maxImplSize ? ctx->Point.MaxSize : maxImplSize; 513 value[3] = ctx->Point.Threshold; 514 } 515 return; 516 case STATE_LIGHT_SPOT_DIR_NORMALIZED: 517 { 518 /* here, state[2] is the light number */ 519 /* pre-normalize spot dir */ 520 const GLuint ln = (GLuint) state[2]; 521 COPY_3V(value, ctx->Light.Light[ln]._NormSpotDirection); 522 value[3] = ctx->Light.Light[ln]._CosCutoff; 523 } 524 return; 525 526 case STATE_LIGHT_POSITION: 527 { 528 const GLuint ln = (GLuint) state[2]; 529 COPY_4V(value, ctx->Light.Light[ln]._Position); 530 } 531 return; 532 533 case STATE_LIGHT_POSITION_NORMALIZED: 534 { 535 const GLuint ln = (GLuint) state[2]; 536 COPY_4V(value, ctx->Light.Light[ln]._Position); 537 NORMALIZE_3FV( value ); 538 } 539 return; 540 541 case STATE_LIGHT_HALF_VECTOR: 542 { 543 const GLuint ln = (GLuint) state[2]; 544 GLfloat p[3]; 545 /* Compute infinite half angle vector: 546 * halfVector = normalize(normalize(lightPos) + (0, 0, 1)) 547 * light.EyePosition.w should be 0 for infinite lights. 548 */ 549 COPY_3V(p, ctx->Light.Light[ln]._Position); 550 NORMALIZE_3FV(p); 551 ADD_3V(value, p, ctx->_EyeZDir); 552 NORMALIZE_3FV(value); 553 value[3] = 1.0; 554 } 555 return; 556 557 case STATE_PT_SCALE: 558 value[0] = ctx->Pixel.RedScale; 559 value[1] = ctx->Pixel.GreenScale; 560 value[2] = ctx->Pixel.BlueScale; 561 value[3] = ctx->Pixel.AlphaScale; 562 return; 563 564 case STATE_PT_BIAS: 565 value[0] = ctx->Pixel.RedBias; 566 value[1] = ctx->Pixel.GreenBias; 567 value[2] = ctx->Pixel.BlueBias; 568 value[3] = ctx->Pixel.AlphaBias; 569 return; 570 571 case STATE_FB_SIZE: 572 value[0] = (GLfloat) (ctx->DrawBuffer->Width - 1); 573 value[1] = (GLfloat) (ctx->DrawBuffer->Height - 1); 574 value[2] = 0.0F; 575 value[3] = 0.0F; 576 return; 577 578 case STATE_FB_WPOS_Y_TRANSFORM: 579 /* A driver may negate this conditional by using ZW swizzle 580 * instead of XY (based on e.g. some other state). */ 581 if (_mesa_is_user_fbo(ctx->DrawBuffer)) { 582 /* Identity (XY) followed by flipping Y upside down (ZW). */ 583 value[0] = 1.0F; 584 value[1] = 0.0F; 585 value[2] = -1.0F; 586 value[3] = (GLfloat) ctx->DrawBuffer->Height; 587 } else { 588 /* Flipping Y upside down (XY) followed by identity (ZW). */ 589 value[0] = -1.0F; 590 value[1] = (GLfloat) ctx->DrawBuffer->Height; 591 value[2] = 1.0F; 592 value[3] = 0.0F; 593 } 594 return; 595 596 /* XXX: make sure new tokens added here are also handled in the 597 * _mesa_program_state_flags() switch, below. 598 */ 599 default: 600 /* Unknown state indexes are silently ignored here. 601 * Drivers may do something special. 602 */ 603 return; 604 } 605 return; 606 607 default: 608 _mesa_problem(ctx, "Invalid state in _mesa_fetch_state"); 609 return; 610 } 611} 612 613 614/** 615 * Return a bitmask of the Mesa state flags (_NEW_* values) which would 616 * indicate that the given context state may have changed. 617 * The bitmask is used during validation to determine if we need to update 618 * vertex/fragment program parameters (like "state.material.color") when 619 * some GL state has changed. 620 */ 621GLbitfield 622_mesa_program_state_flags(const gl_state_index state[STATE_LENGTH]) 623{ 624 switch (state[0]) { 625 case STATE_MATERIAL: 626 case STATE_LIGHTPROD: 627 case STATE_LIGHTMODEL_SCENECOLOR: 628 /* these can be effected by glColor when colormaterial mode is used */ 629 return _NEW_LIGHT | _NEW_CURRENT_ATTRIB; 630 631 case STATE_LIGHT: 632 case STATE_LIGHTMODEL_AMBIENT: 633 return _NEW_LIGHT; 634 635 case STATE_TEXGEN: 636 return _NEW_TEXTURE; 637 case STATE_TEXENV_COLOR: 638 return _NEW_TEXTURE | _NEW_BUFFERS | _NEW_FRAG_CLAMP; 639 640 case STATE_FOG_COLOR: 641 return _NEW_FOG | _NEW_BUFFERS | _NEW_FRAG_CLAMP; 642 case STATE_FOG_PARAMS: 643 return _NEW_FOG; 644 645 case STATE_CLIPPLANE: 646 return _NEW_TRANSFORM; 647 648 case STATE_POINT_SIZE: 649 case STATE_POINT_ATTENUATION: 650 return _NEW_POINT; 651 652 case STATE_MODELVIEW_MATRIX: 653 return _NEW_MODELVIEW; 654 case STATE_PROJECTION_MATRIX: 655 return _NEW_PROJECTION; 656 case STATE_MVP_MATRIX: 657 return _NEW_MODELVIEW | _NEW_PROJECTION; 658 case STATE_TEXTURE_MATRIX: 659 return _NEW_TEXTURE_MATRIX; 660 case STATE_PROGRAM_MATRIX: 661 return _NEW_TRACK_MATRIX; 662 663 case STATE_NUM_SAMPLES: 664 return _NEW_BUFFERS; 665 666 case STATE_DEPTH_RANGE: 667 return _NEW_VIEWPORT; 668 669 case STATE_FRAGMENT_PROGRAM: 670 case STATE_VERTEX_PROGRAM: 671 return _NEW_PROGRAM; 672 673 case STATE_NORMAL_SCALE: 674 return _NEW_MODELVIEW; 675 676 case STATE_INTERNAL: 677 switch (state[1]) { 678 case STATE_CURRENT_ATTRIB: 679 return _NEW_CURRENT_ATTRIB; 680 case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED: 681 return _NEW_CURRENT_ATTRIB | _NEW_LIGHT | _NEW_BUFFERS; 682 683 case STATE_NORMAL_SCALE: 684 return _NEW_MODELVIEW; 685 686 case STATE_TEXRECT_SCALE: 687 return _NEW_TEXTURE; 688 case STATE_FOG_PARAMS_OPTIMIZED: 689 return _NEW_FOG; 690 case STATE_POINT_SIZE_CLAMPED: 691 return _NEW_POINT | _NEW_MULTISAMPLE; 692 case STATE_LIGHT_SPOT_DIR_NORMALIZED: 693 case STATE_LIGHT_POSITION: 694 case STATE_LIGHT_POSITION_NORMALIZED: 695 case STATE_LIGHT_HALF_VECTOR: 696 return _NEW_LIGHT; 697 698 case STATE_PT_SCALE: 699 case STATE_PT_BIAS: 700 return _NEW_PIXEL; 701 702 case STATE_FB_SIZE: 703 case STATE_FB_WPOS_Y_TRANSFORM: 704 return _NEW_BUFFERS; 705 706 default: 707 /* unknown state indexes are silently ignored and 708 * no flag set, since it is handled by the driver. 709 */ 710 return 0; 711 } 712 713 default: 714 _mesa_problem(NULL, "unexpected state[0] in make_state_flags()"); 715 return 0; 716 } 717} 718 719 720static void 721append(char *dst, const char *src) 722{ 723 while (*dst) 724 dst++; 725 while (*src) 726 *dst++ = *src++; 727 *dst = 0; 728} 729 730 731/** 732 * Convert token 'k' to a string, append it onto 'dst' string. 733 */ 734static void 735append_token(char *dst, gl_state_index k) 736{ 737 switch (k) { 738 case STATE_MATERIAL: 739 append(dst, "material"); 740 break; 741 case STATE_LIGHT: 742 append(dst, "light"); 743 break; 744 case STATE_LIGHTMODEL_AMBIENT: 745 append(dst, "lightmodel.ambient"); 746 break; 747 case STATE_LIGHTMODEL_SCENECOLOR: 748 break; 749 case STATE_LIGHTPROD: 750 append(dst, "lightprod"); 751 break; 752 case STATE_TEXGEN: 753 append(dst, "texgen"); 754 break; 755 case STATE_FOG_COLOR: 756 append(dst, "fog.color"); 757 break; 758 case STATE_FOG_PARAMS: 759 append(dst, "fog.params"); 760 break; 761 case STATE_CLIPPLANE: 762 append(dst, "clip"); 763 break; 764 case STATE_POINT_SIZE: 765 append(dst, "point.size"); 766 break; 767 case STATE_POINT_ATTENUATION: 768 append(dst, "point.attenuation"); 769 break; 770 case STATE_MODELVIEW_MATRIX: 771 append(dst, "matrix.modelview"); 772 break; 773 case STATE_PROJECTION_MATRIX: 774 append(dst, "matrix.projection"); 775 break; 776 case STATE_MVP_MATRIX: 777 append(dst, "matrix.mvp"); 778 break; 779 case STATE_TEXTURE_MATRIX: 780 append(dst, "matrix.texture"); 781 break; 782 case STATE_PROGRAM_MATRIX: 783 append(dst, "matrix.program"); 784 break; 785 case STATE_MATRIX_INVERSE: 786 append(dst, ".inverse"); 787 break; 788 case STATE_MATRIX_TRANSPOSE: 789 append(dst, ".transpose"); 790 break; 791 case STATE_MATRIX_INVTRANS: 792 append(dst, ".invtrans"); 793 break; 794 case STATE_AMBIENT: 795 append(dst, ".ambient"); 796 break; 797 case STATE_DIFFUSE: 798 append(dst, ".diffuse"); 799 break; 800 case STATE_SPECULAR: 801 append(dst, ".specular"); 802 break; 803 case STATE_EMISSION: 804 append(dst, ".emission"); 805 break; 806 case STATE_SHININESS: 807 append(dst, "lshininess"); 808 break; 809 case STATE_HALF_VECTOR: 810 append(dst, ".half"); 811 break; 812 case STATE_POSITION: 813 append(dst, ".position"); 814 break; 815 case STATE_ATTENUATION: 816 append(dst, ".attenuation"); 817 break; 818 case STATE_SPOT_DIRECTION: 819 append(dst, ".spot.direction"); 820 break; 821 case STATE_SPOT_CUTOFF: 822 append(dst, ".spot.cutoff"); 823 break; 824 case STATE_TEXGEN_EYE_S: 825 append(dst, ".eye.s"); 826 break; 827 case STATE_TEXGEN_EYE_T: 828 append(dst, ".eye.t"); 829 break; 830 case STATE_TEXGEN_EYE_R: 831 append(dst, ".eye.r"); 832 break; 833 case STATE_TEXGEN_EYE_Q: 834 append(dst, ".eye.q"); 835 break; 836 case STATE_TEXGEN_OBJECT_S: 837 append(dst, ".object.s"); 838 break; 839 case STATE_TEXGEN_OBJECT_T: 840 append(dst, ".object.t"); 841 break; 842 case STATE_TEXGEN_OBJECT_R: 843 append(dst, ".object.r"); 844 break; 845 case STATE_TEXGEN_OBJECT_Q: 846 append(dst, ".object.q"); 847 break; 848 case STATE_TEXENV_COLOR: 849 append(dst, "texenv"); 850 break; 851 case STATE_NUM_SAMPLES: 852 append(dst, "numsamples"); 853 break; 854 case STATE_DEPTH_RANGE: 855 append(dst, "depth.range"); 856 break; 857 case STATE_VERTEX_PROGRAM: 858 case STATE_FRAGMENT_PROGRAM: 859 break; 860 case STATE_ENV: 861 append(dst, "env"); 862 break; 863 case STATE_LOCAL: 864 append(dst, "local"); 865 break; 866 /* BEGIN internal state vars */ 867 case STATE_INTERNAL: 868 append(dst, ".internal."); 869 break; 870 case STATE_CURRENT_ATTRIB: 871 append(dst, "current"); 872 break; 873 case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED: 874 append(dst, "currentAttribMaybeVPClamped"); 875 break; 876 case STATE_NORMAL_SCALE: 877 append(dst, "normalScale"); 878 break; 879 case STATE_TEXRECT_SCALE: 880 append(dst, "texrectScale"); 881 break; 882 case STATE_FOG_PARAMS_OPTIMIZED: 883 append(dst, "fogParamsOptimized"); 884 break; 885 case STATE_POINT_SIZE_CLAMPED: 886 append(dst, "pointSizeClamped"); 887 break; 888 case STATE_LIGHT_SPOT_DIR_NORMALIZED: 889 append(dst, "lightSpotDirNormalized"); 890 break; 891 case STATE_LIGHT_POSITION: 892 append(dst, "lightPosition"); 893 break; 894 case STATE_LIGHT_POSITION_NORMALIZED: 895 append(dst, "light.position.normalized"); 896 break; 897 case STATE_LIGHT_HALF_VECTOR: 898 append(dst, "lightHalfVector"); 899 break; 900 case STATE_PT_SCALE: 901 append(dst, "PTscale"); 902 break; 903 case STATE_PT_BIAS: 904 append(dst, "PTbias"); 905 break; 906 case STATE_FB_SIZE: 907 append(dst, "FbSize"); 908 break; 909 case STATE_FB_WPOS_Y_TRANSFORM: 910 append(dst, "FbWposYTransform"); 911 break; 912 default: 913 /* probably STATE_INTERNAL_DRIVER+i (driver private state) */ 914 append(dst, "driverState"); 915 } 916} 917 918static void 919append_face(char *dst, GLint face) 920{ 921 if (face == 0) 922 append(dst, "front."); 923 else 924 append(dst, "back."); 925} 926 927static void 928append_index(char *dst, GLint index) 929{ 930 char s[20]; 931 sprintf(s, "[%d]", index); 932 append(dst, s); 933} 934 935/** 936 * Make a string from the given state vector. 937 * For example, return "state.matrix.texture[2].inverse". 938 * Use free() to deallocate the string. 939 */ 940char * 941_mesa_program_state_string(const gl_state_index state[STATE_LENGTH]) 942{ 943 char str[1000] = ""; 944 char tmp[30]; 945 946 append(str, "state."); 947 append_token(str, state[0]); 948 949 switch (state[0]) { 950 case STATE_MATERIAL: 951 append_face(str, state[1]); 952 append_token(str, state[2]); 953 break; 954 case STATE_LIGHT: 955 append_index(str, state[1]); /* light number [i]. */ 956 append_token(str, state[2]); /* coefficients */ 957 break; 958 case STATE_LIGHTMODEL_AMBIENT: 959 append(str, "lightmodel.ambient"); 960 break; 961 case STATE_LIGHTMODEL_SCENECOLOR: 962 if (state[1] == 0) { 963 append(str, "lightmodel.front.scenecolor"); 964 } 965 else { 966 append(str, "lightmodel.back.scenecolor"); 967 } 968 break; 969 case STATE_LIGHTPROD: 970 append_index(str, state[1]); /* light number [i]. */ 971 append_face(str, state[2]); 972 append_token(str, state[3]); 973 break; 974 case STATE_TEXGEN: 975 append_index(str, state[1]); /* tex unit [i] */ 976 append_token(str, state[2]); /* plane coef */ 977 break; 978 case STATE_TEXENV_COLOR: 979 append_index(str, state[1]); /* tex unit [i] */ 980 append(str, "color"); 981 break; 982 case STATE_CLIPPLANE: 983 append_index(str, state[1]); /* plane [i] */ 984 append(str, ".plane"); 985 break; 986 case STATE_MODELVIEW_MATRIX: 987 case STATE_PROJECTION_MATRIX: 988 case STATE_MVP_MATRIX: 989 case STATE_TEXTURE_MATRIX: 990 case STATE_PROGRAM_MATRIX: 991 { 992 /* state[0] = modelview, projection, texture, etc. */ 993 /* state[1] = which texture matrix or program matrix */ 994 /* state[2] = first row to fetch */ 995 /* state[3] = last row to fetch */ 996 /* state[4] = transpose, inverse or invtrans */ 997 const gl_state_index mat = state[0]; 998 const GLuint index = (GLuint) state[1]; 999 const GLuint firstRow = (GLuint) state[2]; 1000 const GLuint lastRow = (GLuint) state[3]; 1001 const gl_state_index modifier = state[4]; 1002 if (index || 1003 mat == STATE_TEXTURE_MATRIX || 1004 mat == STATE_PROGRAM_MATRIX) 1005 append_index(str, index); 1006 if (modifier) 1007 append_token(str, modifier); 1008 if (firstRow == lastRow) 1009 sprintf(tmp, ".row[%d]", firstRow); 1010 else 1011 sprintf(tmp, ".row[%d..%d]", firstRow, lastRow); 1012 append(str, tmp); 1013 } 1014 break; 1015 case STATE_POINT_SIZE: 1016 break; 1017 case STATE_POINT_ATTENUATION: 1018 break; 1019 case STATE_FOG_PARAMS: 1020 break; 1021 case STATE_FOG_COLOR: 1022 break; 1023 case STATE_NUM_SAMPLES: 1024 break; 1025 case STATE_DEPTH_RANGE: 1026 break; 1027 case STATE_FRAGMENT_PROGRAM: 1028 case STATE_VERTEX_PROGRAM: 1029 /* state[1] = {STATE_ENV, STATE_LOCAL} */ 1030 /* state[2] = parameter index */ 1031 append_token(str, state[1]); 1032 append_index(str, state[2]); 1033 break; 1034 case STATE_NORMAL_SCALE: 1035 break; 1036 case STATE_INTERNAL: 1037 append_token(str, state[1]); 1038 if (state[1] == STATE_CURRENT_ATTRIB) 1039 append_index(str, state[2]); 1040 break; 1041 default: 1042 _mesa_problem(NULL, "Invalid state in _mesa_program_state_string"); 1043 break; 1044 } 1045 1046 return _mesa_strdup(str); 1047} 1048 1049 1050/** 1051 * Loop over all the parameters in a parameter list. If the parameter 1052 * is a GL state reference, look up the current value of that state 1053 * variable and put it into the parameter's Value[4] array. 1054 * Other parameter types never change or are explicitly set by the user 1055 * with glUniform() or glProgramParameter(), etc. 1056 * This would be called at glBegin time. 1057 */ 1058void 1059_mesa_load_state_parameters(struct gl_context *ctx, 1060 struct gl_program_parameter_list *paramList) 1061{ 1062 GLuint i; 1063 1064 if (!paramList) 1065 return; 1066 1067 for (i = 0; i < paramList->NumParameters; i++) { 1068 if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) { 1069 _mesa_fetch_state(ctx, 1070 paramList->Parameters[i].StateIndexes, 1071 ¶mList->ParameterValues[i][0].f); 1072 } 1073 } 1074} 1075