2
* Mesa 3-D graphics library
5
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
7
* Permission is hereby granted, free of charge, to any person obtaining a
8
* copy of this software and associated documentation files (the "Software"),
9
* to deal in the Software without restriction, including without limitation
10
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
* and/or sell copies of the Software, and to permit persons to whom the
12
* Software is furnished to do so, subject to the following conditions:
14
* The above copyright notice and this permission notice shall be included
15
* in all copies or substantial portions of the Software.
17
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
* \file prog_statevars.c
27
* Program state variable management.
32
#include "main/glheader.h"
33
#include "main/context.h"
34
#include "main/imports.h"
35
#include "main/macros.h"
36
#include "main/mtypes.h"
37
#include "prog_statevars.h"
38
#include "prog_parameter.h"
42
* Use the list of tokens in the state[] array to find global GL state
43
* and return it in <value>. Usually, four values are returned in <value>
44
* but matrix queries may return as many as 16 values.
45
* This function is used for ARB vertex/fragment programs.
46
* The program parser will produce the state[] values.
49
_mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
55
/* state[1] is either 0=front or 1=back side */
56
const GLuint face = (GLuint) state[1];
57
const struct gl_material *mat = &ctx->Light.Material;
58
ASSERT(face == 0 || face == 1);
59
/* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */
60
ASSERT(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT);
61
/* XXX we could get rid of this switch entirely with a little
62
* work in arbprogparse.c's parse_state_single_item().
64
/* state[2] is the material attribute */
67
COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]);
70
COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]);
73
COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]);
76
COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]);
79
value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0];
85
_mesa_problem(ctx, "Invalid material state in fetch_state");
91
/* state[1] is the light number */
92
const GLuint ln = (GLuint) state[1];
93
/* state[2] is the light attribute */
96
COPY_4V(value, ctx->Light.Light[ln].Ambient);
99
COPY_4V(value, ctx->Light.Light[ln].Diffuse);
102
COPY_4V(value, ctx->Light.Light[ln].Specular);
105
COPY_4V(value, ctx->Light.Light[ln].EyePosition);
107
case STATE_ATTENUATION:
108
value[0] = ctx->Light.Light[ln].ConstantAttenuation;
109
value[1] = ctx->Light.Light[ln].LinearAttenuation;
110
value[2] = ctx->Light.Light[ln].QuadraticAttenuation;
111
value[3] = ctx->Light.Light[ln].SpotExponent;
113
case STATE_SPOT_DIRECTION:
114
COPY_3V(value, ctx->Light.Light[ln].SpotDirection);
115
value[3] = ctx->Light.Light[ln]._CosCutoff;
117
case STATE_SPOT_CUTOFF:
118
value[0] = ctx->Light.Light[ln].SpotCutoff;
120
case STATE_HALF_VECTOR:
122
static const GLfloat eye_z[] = {0, 0, 1};
124
/* Compute infinite half angle vector:
125
* halfVector = normalize(normalize(lightPos) + (0, 0, 1))
126
* light.EyePosition.w should be 0 for infinite lights.
128
COPY_3V(p, ctx->Light.Light[ln].EyePosition);
130
ADD_3V(value, p, eye_z);
131
NORMALIZE_3FV(value);
136
_mesa_problem(ctx, "Invalid light state in fetch_state");
140
case STATE_LIGHTMODEL_AMBIENT:
141
COPY_4V(value, ctx->Light.Model.Ambient);
143
case STATE_LIGHTMODEL_SCENECOLOR:
147
for (i = 0; i < 3; i++) {
148
value[i] = ctx->Light.Model.Ambient[i]
149
* ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i]
150
+ ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i];
152
value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
157
for (i = 0; i < 3; i++) {
158
value[i] = ctx->Light.Model.Ambient[i]
159
* ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i]
160
+ ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i];
162
value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
165
case STATE_LIGHTPROD:
167
const GLuint ln = (GLuint) state[1];
168
const GLuint face = (GLuint) state[2];
170
ASSERT(face == 0 || face == 1);
173
for (i = 0; i < 3; i++) {
174
value[i] = ctx->Light.Light[ln].Ambient[i] *
175
ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i];
177
/* [3] = material alpha */
178
value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][3];
181
for (i = 0; i < 3; i++) {
182
value[i] = ctx->Light.Light[ln].Diffuse[i] *
183
ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][i];
185
/* [3] = material alpha */
186
value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
189
for (i = 0; i < 3; i++) {
190
value[i] = ctx->Light.Light[ln].Specular[i] *
191
ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i];
193
/* [3] = material alpha */
194
value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][3];
197
_mesa_problem(ctx, "Invalid lightprod state in fetch_state");
203
/* state[1] is the texture unit */
204
const GLuint unit = (GLuint) state[1];
205
/* state[2] is the texgen attribute */
207
case STATE_TEXGEN_EYE_S:
208
COPY_4V(value, ctx->Texture.Unit[unit].GenS.EyePlane);
210
case STATE_TEXGEN_EYE_T:
211
COPY_4V(value, ctx->Texture.Unit[unit].GenT.EyePlane);
213
case STATE_TEXGEN_EYE_R:
214
COPY_4V(value, ctx->Texture.Unit[unit].GenR.EyePlane);
216
case STATE_TEXGEN_EYE_Q:
217
COPY_4V(value, ctx->Texture.Unit[unit].GenQ.EyePlane);
219
case STATE_TEXGEN_OBJECT_S:
220
COPY_4V(value, ctx->Texture.Unit[unit].GenS.ObjectPlane);
222
case STATE_TEXGEN_OBJECT_T:
223
COPY_4V(value, ctx->Texture.Unit[unit].GenT.ObjectPlane);
225
case STATE_TEXGEN_OBJECT_R:
226
COPY_4V(value, ctx->Texture.Unit[unit].GenR.ObjectPlane);
228
case STATE_TEXGEN_OBJECT_Q:
229
COPY_4V(value, ctx->Texture.Unit[unit].GenQ.ObjectPlane);
232
_mesa_problem(ctx, "Invalid texgen state in fetch_state");
236
case STATE_TEXENV_COLOR:
238
/* state[1] is the texture unit */
239
const GLuint unit = (GLuint) state[1];
240
COPY_4V(value, ctx->Texture.Unit[unit].EnvColor);
243
case STATE_FOG_COLOR:
244
COPY_4V(value, ctx->Fog.Color);
246
case STATE_FOG_PARAMS:
247
value[0] = ctx->Fog.Density;
248
value[1] = ctx->Fog.Start;
249
value[2] = ctx->Fog.End;
250
value[3] = (ctx->Fog.End == ctx->Fog.Start)
251
? 1.0f : (GLfloat)(1.0 / (ctx->Fog.End - ctx->Fog.Start));
253
case STATE_CLIPPLANE:
255
const GLuint plane = (GLuint) state[1];
256
COPY_4V(value, ctx->Transform.EyeUserPlane[plane]);
259
case STATE_POINT_SIZE:
260
value[0] = ctx->Point.Size;
261
value[1] = ctx->Point.MinSize;
262
value[2] = ctx->Point.MaxSize;
263
value[3] = ctx->Point.Threshold;
265
case STATE_POINT_ATTENUATION:
266
value[0] = ctx->Point.Params[0];
267
value[1] = ctx->Point.Params[1];
268
value[2] = ctx->Point.Params[2];
271
case STATE_MODELVIEW_MATRIX:
272
case STATE_PROJECTION_MATRIX:
273
case STATE_MVP_MATRIX:
274
case STATE_TEXTURE_MATRIX:
275
case STATE_PROGRAM_MATRIX:
276
case STATE_COLOR_MATRIX:
278
/* state[0] = modelview, projection, texture, etc. */
279
/* state[1] = which texture matrix or program matrix */
280
/* state[2] = first row to fetch */
281
/* state[3] = last row to fetch */
282
/* state[4] = transpose, inverse or invtrans */
283
const GLmatrix *matrix;
284
const gl_state_index mat = state[0];
285
const GLuint index = (GLuint) state[1];
286
const GLuint firstRow = (GLuint) state[2];
287
const GLuint lastRow = (GLuint) state[3];
288
const gl_state_index modifier = state[4];
291
ASSERT(firstRow >= 0);
292
ASSERT(firstRow < 4);
293
ASSERT(lastRow >= 0);
295
if (mat == STATE_MODELVIEW_MATRIX) {
296
matrix = ctx->ModelviewMatrixStack.Top;
298
else if (mat == STATE_PROJECTION_MATRIX) {
299
matrix = ctx->ProjectionMatrixStack.Top;
301
else if (mat == STATE_MVP_MATRIX) {
302
matrix = &ctx->_ModelProjectMatrix;
304
else if (mat == STATE_TEXTURE_MATRIX) {
305
ASSERT(index < Elements(ctx->TextureMatrixStack));
306
matrix = ctx->TextureMatrixStack[index].Top;
308
else if (mat == STATE_PROGRAM_MATRIX) {
309
ASSERT(index < Elements(ctx->ProgramMatrixStack));
310
matrix = ctx->ProgramMatrixStack[index].Top;
312
else if (mat == STATE_COLOR_MATRIX) {
313
matrix = ctx->ColorMatrixStack.Top;
316
_mesa_problem(ctx, "Bad matrix name in _mesa_fetch_state()");
319
if (modifier == STATE_MATRIX_INVERSE ||
320
modifier == STATE_MATRIX_INVTRANS) {
321
/* Be sure inverse is up to date:
323
_math_matrix_alloc_inv( (GLmatrix *) matrix );
324
_math_matrix_analyse( (GLmatrix*) matrix );
330
if (modifier == STATE_MATRIX_TRANSPOSE ||
331
modifier == STATE_MATRIX_INVTRANS) {
332
for (i = 0, row = firstRow; row <= lastRow; row++) {
333
value[i++] = m[row * 4 + 0];
334
value[i++] = m[row * 4 + 1];
335
value[i++] = m[row * 4 + 2];
336
value[i++] = m[row * 4 + 3];
340
for (i = 0, row = firstRow; row <= lastRow; row++) {
341
value[i++] = m[row + 0];
342
value[i++] = m[row + 4];
343
value[i++] = m[row + 8];
344
value[i++] = m[row + 12];
349
case STATE_DEPTH_RANGE:
350
value[0] = ctx->Viewport.Near; /* near */
351
value[1] = ctx->Viewport.Far; /* far */
352
value[2] = ctx->Viewport.Far - ctx->Viewport.Near; /* far - near */
355
case STATE_FRAGMENT_PROGRAM:
357
/* state[1] = {STATE_ENV, STATE_LOCAL} */
358
/* state[2] = parameter index */
359
const int idx = (int) state[2];
362
COPY_4V(value, ctx->FragmentProgram.Parameters[idx]);
365
COPY_4V(value, ctx->FragmentProgram.Current->Base.LocalParams[idx]);
368
_mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
374
case STATE_VERTEX_PROGRAM:
376
/* state[1] = {STATE_ENV, STATE_LOCAL} */
377
/* state[2] = parameter index */
378
const int idx = (int) state[2];
381
COPY_4V(value, ctx->VertexProgram.Parameters[idx]);
384
COPY_4V(value, ctx->VertexProgram.Current->Base.LocalParams[idx]);
387
_mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
393
case STATE_NORMAL_SCALE:
394
ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1);
399
case STATE_CURRENT_ATTRIB:
401
const GLuint idx = (GLuint) state[2];
402
COPY_4V(value, ctx->Current.Attrib[idx]);
406
case STATE_NORMAL_SCALE:
408
ctx->_ModelViewInvScale,
409
ctx->_ModelViewInvScale,
410
ctx->_ModelViewInvScale,
414
case STATE_TEXRECT_SCALE:
415
/* Value = { 1/texWidth, 1/texHeight, 0, 1 }.
416
* Used to convert unnormalized texcoords to normalized texcoords.
419
const int unit = (int) state[2];
420
const struct gl_texture_object *texObj
421
= ctx->Texture.Unit[unit]._Current;
423
struct gl_texture_image *texImage = texObj->Image[0][0];
425
(GLfloat) (1.0 / texImage->Width),
426
(GLfloat) (1.0 / texImage->Height),
432
case STATE_FOG_PARAMS_OPTIMIZED:
433
/* for simpler per-vertex/pixel fog calcs. POW (for EXP/EXP2 fog)
434
* might be more expensive than EX2 on some hw, plus it needs
435
* another constant (e) anyway. Linear fog can now be done with a
437
* linear: fogcoord * -1/(end-start) + end/(end-start)
438
* exp: 2^-(density/ln(2) * fogcoord)
439
* exp2: 2^-((density/(ln(2)^2) * fogcoord)^2)
441
value[0] = (ctx->Fog.End == ctx->Fog.Start)
442
? 1.0f : (GLfloat)(-1.0F / (ctx->Fog.End - ctx->Fog.Start));
443
value[1] = ctx->Fog.End * -value[0];
444
value[2] = (GLfloat)(ctx->Fog.Density * ONE_DIV_LN2);
445
value[3] = (GLfloat)(ctx->Fog.Density * ONE_DIV_SQRT_LN2);
448
case STATE_POINT_SIZE_CLAMPED:
450
/* this includes implementation dependent limits, to avoid
451
* another potentially necessary clamp.
452
* Note: for sprites, point smooth (point AA) is ignored
453
* and we'll clamp to MinPointSizeAA and MaxPointSize, because we
454
* expect drivers will want to say their minimum for AA size is 0.0
455
* but for non-AA it's 1.0 (because normal points with size below 1.0
456
* need to get rounded up to 1.0, hence never disappear). GL does
457
* not specify max clamp size for sprites, other than it needs to be
458
* at least as large as max AA size, hence use non-AA size there.
462
if (ctx->Point.PointSprite) {
463
minImplSize = ctx->Const.MinPointSizeAA;
464
maxImplSize = ctx->Const.MaxPointSize;
466
else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) {
467
minImplSize = ctx->Const.MinPointSizeAA;
468
maxImplSize = ctx->Const.MaxPointSizeAA;
471
minImplSize = ctx->Const.MinPointSize;
472
maxImplSize = ctx->Const.MaxPointSize;
474
value[0] = ctx->Point.Size;
475
value[1] = ctx->Point.MinSize >= minImplSize ? ctx->Point.MinSize : minImplSize;
476
value[2] = ctx->Point.MaxSize <= maxImplSize ? ctx->Point.MaxSize : maxImplSize;
477
value[3] = ctx->Point.Threshold;
480
case STATE_POINT_SIZE_IMPL_CLAMP:
482
/* for implementation clamp only in vs */
485
if (ctx->Point.PointSprite) {
486
minImplSize = ctx->Const.MinPointSizeAA;
487
maxImplSize = ctx->Const.MaxPointSize;
489
else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) {
490
minImplSize = ctx->Const.MinPointSizeAA;
491
maxImplSize = ctx->Const.MaxPointSizeAA;
494
minImplSize = ctx->Const.MinPointSize;
495
maxImplSize = ctx->Const.MaxPointSize;
497
value[0] = ctx->Point.Size;
498
value[1] = minImplSize;
499
value[2] = maxImplSize;
500
value[3] = ctx->Point.Threshold;
503
case STATE_LIGHT_SPOT_DIR_NORMALIZED:
505
/* here, state[2] is the light number */
506
/* pre-normalize spot dir */
507
const GLuint ln = (GLuint) state[2];
508
COPY_3V(value, ctx->Light.Light[ln]._NormSpotDirection);
509
value[3] = ctx->Light.Light[ln]._CosCutoff;
513
case STATE_LIGHT_POSITION:
515
const GLuint ln = (GLuint) state[2];
516
COPY_4V(value, ctx->Light.Light[ln]._Position);
520
case STATE_LIGHT_POSITION_NORMALIZED:
522
const GLuint ln = (GLuint) state[2];
523
COPY_4V(value, ctx->Light.Light[ln]._Position);
524
NORMALIZE_3FV( value );
528
case STATE_LIGHT_HALF_VECTOR:
530
const GLuint ln = (GLuint) state[2];
532
/* Compute infinite half angle vector:
533
* halfVector = normalize(normalize(lightPos) + (0, 0, 1))
534
* light.EyePosition.w should be 0 for infinite lights.
536
COPY_3V(p, ctx->Light.Light[ln]._Position);
538
ADD_3V(value, p, ctx->_EyeZDir);
539
NORMALIZE_3FV(value);
545
value[0] = ctx->Pixel.RedScale;
546
value[1] = ctx->Pixel.GreenScale;
547
value[2] = ctx->Pixel.BlueScale;
548
value[3] = ctx->Pixel.AlphaScale;
552
value[0] = ctx->Pixel.RedBias;
553
value[1] = ctx->Pixel.GreenBias;
554
value[2] = ctx->Pixel.BlueBias;
555
value[3] = ctx->Pixel.AlphaBias;
558
case STATE_PCM_SCALE:
559
COPY_4V(value, ctx->Pixel.PostColorMatrixScale);
563
COPY_4V(value, ctx->Pixel.PostColorMatrixBias);
566
case STATE_SHADOW_AMBIENT:
568
const int unit = (int) state[2];
569
const struct gl_texture_object *texObj
570
= ctx->Texture.Unit[unit]._Current;
575
value[3] = texObj->CompareFailValue;
581
value[0] = (GLfloat) (ctx->DrawBuffer->Width - 1);
582
value[1] = (GLfloat) (ctx->DrawBuffer->Height - 1);
587
case STATE_ROT_MATRIX_0:
589
const int unit = (int) state[2];
590
GLfloat *rotMat22 = ctx->Texture.Unit[unit].RotMatrix;
591
value[0] = rotMat22[0];
592
value[1] = rotMat22[2];
598
case STATE_ROT_MATRIX_1:
600
const int unit = (int) state[2];
601
GLfloat *rotMat22 = ctx->Texture.Unit[unit].RotMatrix;
602
value[0] = rotMat22[1];
603
value[1] = rotMat22[3];
609
/* XXX: make sure new tokens added here are also handled in the
610
* _mesa_program_state_flags() switch, below.
613
/* Unknown state indexes are silently ignored here.
614
* Drivers may do something special.
621
_mesa_problem(ctx, "Invalid state in _mesa_fetch_state");
628
* Return a bitmask of the Mesa state flags (_NEW_* values) which would
629
* indicate that the given context state may have changed.
630
* The bitmask is used during validation to determine if we need to update
631
* vertex/fragment program parameters (like "state.material.color") when
632
* some GL state has changed.
635
_mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
640
case STATE_LIGHTMODEL_AMBIENT:
641
case STATE_LIGHTMODEL_SCENECOLOR:
642
case STATE_LIGHTPROD:
646
case STATE_TEXENV_COLOR:
649
case STATE_FOG_COLOR:
650
case STATE_FOG_PARAMS:
653
case STATE_CLIPPLANE:
654
return _NEW_TRANSFORM;
656
case STATE_POINT_SIZE:
657
case STATE_POINT_ATTENUATION:
660
case STATE_MODELVIEW_MATRIX:
661
return _NEW_MODELVIEW;
662
case STATE_PROJECTION_MATRIX:
663
return _NEW_PROJECTION;
664
case STATE_MVP_MATRIX:
665
return _NEW_MODELVIEW | _NEW_PROJECTION;
666
case STATE_TEXTURE_MATRIX:
667
return _NEW_TEXTURE_MATRIX;
668
case STATE_PROGRAM_MATRIX:
669
return _NEW_TRACK_MATRIX;
670
case STATE_COLOR_MATRIX:
671
return _NEW_COLOR_MATRIX;
673
case STATE_DEPTH_RANGE:
674
return _NEW_VIEWPORT;
676
case STATE_FRAGMENT_PROGRAM:
677
case STATE_VERTEX_PROGRAM:
680
case STATE_NORMAL_SCALE:
681
return _NEW_MODELVIEW;
685
case STATE_CURRENT_ATTRIB:
686
return _NEW_CURRENT_ATTRIB;
688
case STATE_NORMAL_SCALE:
689
return _NEW_MODELVIEW;
691
case STATE_TEXRECT_SCALE:
692
case STATE_SHADOW_AMBIENT:
693
case STATE_ROT_MATRIX_0:
694
case STATE_ROT_MATRIX_1:
696
case STATE_FOG_PARAMS_OPTIMIZED:
698
case STATE_POINT_SIZE_CLAMPED:
699
case STATE_POINT_SIZE_IMPL_CLAMP:
700
return _NEW_POINT | _NEW_MULTISAMPLE;
701
case STATE_LIGHT_SPOT_DIR_NORMALIZED:
702
case STATE_LIGHT_POSITION:
703
case STATE_LIGHT_POSITION_NORMALIZED:
704
case STATE_LIGHT_HALF_VECTOR:
709
case STATE_PCM_SCALE:
717
/* unknown state indexes are silently ignored and
718
* no flag set, since it is handled by the driver.
724
_mesa_problem(NULL, "unexpected state[0] in make_state_flags()");
731
append(char *dst, const char *src)
742
* Convert token 'k' to a string, append it onto 'dst' string.
745
append_token(char *dst, gl_state_index k)
749
append(dst, "material");
752
append(dst, "light");
754
case STATE_LIGHTMODEL_AMBIENT:
755
append(dst, "lightmodel.ambient");
757
case STATE_LIGHTMODEL_SCENECOLOR:
759
case STATE_LIGHTPROD:
760
append(dst, "lightprod");
763
append(dst, "texgen");
765
case STATE_FOG_COLOR:
766
append(dst, "fog.color");
768
case STATE_FOG_PARAMS:
769
append(dst, "fog.params");
771
case STATE_CLIPPLANE:
774
case STATE_POINT_SIZE:
775
append(dst, "point.size");
777
case STATE_POINT_ATTENUATION:
778
append(dst, "point.attenuation");
780
case STATE_MODELVIEW_MATRIX:
781
append(dst, "matrix.modelview");
783
case STATE_PROJECTION_MATRIX:
784
append(dst, "matrix.projection");
786
case STATE_MVP_MATRIX:
787
append(dst, "matrix.mvp");
789
case STATE_TEXTURE_MATRIX:
790
append(dst, "matrix.texture");
792
case STATE_PROGRAM_MATRIX:
793
append(dst, "matrix.program");
795
case STATE_COLOR_MATRIX:
796
append(dst, "matrix.color");
798
case STATE_MATRIX_INVERSE:
799
append(dst, ".inverse");
801
case STATE_MATRIX_TRANSPOSE:
802
append(dst, ".transpose");
804
case STATE_MATRIX_INVTRANS:
805
append(dst, ".invtrans");
808
append(dst, ".ambient");
811
append(dst, ".diffuse");
814
append(dst, ".specular");
817
append(dst, ".emission");
819
case STATE_SHININESS:
820
append(dst, "lshininess");
822
case STATE_HALF_VECTOR:
823
append(dst, ".half");
826
append(dst, ".position");
828
case STATE_ATTENUATION:
829
append(dst, ".attenuation");
831
case STATE_SPOT_DIRECTION:
832
append(dst, ".spot.direction");
834
case STATE_SPOT_CUTOFF:
835
append(dst, ".spot.cutoff");
837
case STATE_TEXGEN_EYE_S:
838
append(dst, ".eye.s");
840
case STATE_TEXGEN_EYE_T:
841
append(dst, ".eye.t");
843
case STATE_TEXGEN_EYE_R:
844
append(dst, ".eye.r");
846
case STATE_TEXGEN_EYE_Q:
847
append(dst, ".eye.q");
849
case STATE_TEXGEN_OBJECT_S:
850
append(dst, ".object.s");
852
case STATE_TEXGEN_OBJECT_T:
853
append(dst, ".object.t");
855
case STATE_TEXGEN_OBJECT_R:
856
append(dst, ".object.r");
858
case STATE_TEXGEN_OBJECT_Q:
859
append(dst, ".object.q");
861
case STATE_TEXENV_COLOR:
862
append(dst, "texenv");
864
case STATE_DEPTH_RANGE:
865
append(dst, "depth.range");
867
case STATE_VERTEX_PROGRAM:
868
case STATE_FRAGMENT_PROGRAM:
874
append(dst, "local");
876
/* BEGIN internal state vars */
878
append(dst, ".internal.");
880
case STATE_CURRENT_ATTRIB:
881
append(dst, "current");
883
case STATE_NORMAL_SCALE:
884
append(dst, "normalScale");
886
case STATE_TEXRECT_SCALE:
887
append(dst, "texrectScale");
889
case STATE_FOG_PARAMS_OPTIMIZED:
890
append(dst, "fogParamsOptimized");
892
case STATE_POINT_SIZE_CLAMPED:
893
append(dst, "pointSizeClamped");
895
case STATE_POINT_SIZE_IMPL_CLAMP:
896
append(dst, "pointSizeImplClamp");
898
case STATE_LIGHT_SPOT_DIR_NORMALIZED:
899
append(dst, "lightSpotDirNormalized");
901
case STATE_LIGHT_POSITION:
902
append(dst, "lightPosition");
904
case STATE_LIGHT_POSITION_NORMALIZED:
905
append(dst, "light.position.normalized");
907
case STATE_LIGHT_HALF_VECTOR:
908
append(dst, "lightHalfVector");
911
append(dst, "PTscale");
914
append(dst, "PTbias");
916
case STATE_PCM_SCALE:
917
append(dst, "PCMscale");
920
append(dst, "PCMbias");
922
case STATE_SHADOW_AMBIENT:
923
append(dst, "CompareFailValue");
926
append(dst, "FbSize");
928
case STATE_ROT_MATRIX_0:
929
append(dst, "rotMatrixRow0");
931
case STATE_ROT_MATRIX_1:
932
append(dst, "rotMatrixRow1");
935
/* probably STATE_INTERNAL_DRIVER+i (driver private state) */
936
append(dst, "driverState");
941
append_face(char *dst, GLint face)
944
append(dst, "front.");
946
append(dst, "back.");
950
append_index(char *dst, GLint index)
953
sprintf(s, "[%d]", index);
958
* Make a string from the given state vector.
959
* For example, return "state.matrix.texture[2].inverse".
960
* Use free() to deallocate the string.
963
_mesa_program_state_string(const gl_state_index state[STATE_LENGTH])
968
append(str, "state.");
969
append_token(str, state[0]);
973
append_face(str, state[1]);
974
append_token(str, state[2]);
977
append_index(str, state[1]); /* light number [i]. */
978
append_token(str, state[2]); /* coefficients */
980
case STATE_LIGHTMODEL_AMBIENT:
981
append(str, "lightmodel.ambient");
983
case STATE_LIGHTMODEL_SCENECOLOR:
985
append(str, "lightmodel.front.scenecolor");
988
append(str, "lightmodel.back.scenecolor");
991
case STATE_LIGHTPROD:
992
append_index(str, state[1]); /* light number [i]. */
993
append_face(str, state[2]);
994
append_token(str, state[3]);
997
append_index(str, state[1]); /* tex unit [i] */
998
append_token(str, state[2]); /* plane coef */
1000
case STATE_TEXENV_COLOR:
1001
append_index(str, state[1]); /* tex unit [i] */
1002
append(str, "color");
1004
case STATE_CLIPPLANE:
1005
append_index(str, state[1]); /* plane [i] */
1006
append(str, ".plane");
1008
case STATE_MODELVIEW_MATRIX:
1009
case STATE_PROJECTION_MATRIX:
1010
case STATE_MVP_MATRIX:
1011
case STATE_TEXTURE_MATRIX:
1012
case STATE_PROGRAM_MATRIX:
1013
case STATE_COLOR_MATRIX:
1015
/* state[0] = modelview, projection, texture, etc. */
1016
/* state[1] = which texture matrix or program matrix */
1017
/* state[2] = first row to fetch */
1018
/* state[3] = last row to fetch */
1019
/* state[4] = transpose, inverse or invtrans */
1020
const gl_state_index mat = state[0];
1021
const GLuint index = (GLuint) state[1];
1022
const GLuint firstRow = (GLuint) state[2];
1023
const GLuint lastRow = (GLuint) state[3];
1024
const gl_state_index modifier = state[4];
1026
mat == STATE_TEXTURE_MATRIX ||
1027
mat == STATE_PROGRAM_MATRIX)
1028
append_index(str, index);
1030
append_token(str, modifier);
1031
if (firstRow == lastRow)
1032
sprintf(tmp, ".row[%d]", firstRow);
1034
sprintf(tmp, ".row[%d..%d]", firstRow, lastRow);
1038
case STATE_POINT_SIZE:
1040
case STATE_POINT_ATTENUATION:
1042
case STATE_FOG_PARAMS:
1044
case STATE_FOG_COLOR:
1046
case STATE_DEPTH_RANGE:
1048
case STATE_FRAGMENT_PROGRAM:
1049
case STATE_VERTEX_PROGRAM:
1050
/* state[1] = {STATE_ENV, STATE_LOCAL} */
1051
/* state[2] = parameter index */
1052
append_token(str, state[1]);
1053
append_index(str, state[2]);
1055
case STATE_INTERNAL:
1056
append_token(str, state[1]);
1057
if (state[1] == STATE_CURRENT_ATTRIB)
1058
append_index(str, state[2]);
1061
_mesa_problem(NULL, "Invalid state in _mesa_program_state_string");
1065
return _mesa_strdup(str);
1070
* Loop over all the parameters in a parameter list. If the parameter
1071
* is a GL state reference, look up the current value of that state
1072
* variable and put it into the parameter's Value[4] array.
1073
* This would be called at glBegin time when using a fragment program.
1076
_mesa_load_state_parameters(GLcontext *ctx,
1077
struct gl_program_parameter_list *paramList)
1084
/*assert(ctx->Driver.NeedFlush == 0);*/
1086
for (i = 0; i < paramList->NumParameters; i++) {
1087
if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) {
1088
_mesa_fetch_state(ctx,
1089
(gl_state_index *) paramList->Parameters[i].StateIndexes,
1090
paramList->ParameterValues[i]);
1097
* Copy the 16 elements of a matrix into four consecutive program
1098
* registers starting at 'pos'.
1101
load_matrix(GLfloat registers[][4], GLuint pos, const GLfloat mat[16])
1104
for (i = 0; i < 4; i++) {
1105
registers[pos + i][0] = mat[0 + i];
1106
registers[pos + i][1] = mat[4 + i];
1107
registers[pos + i][2] = mat[8 + i];
1108
registers[pos + i][3] = mat[12 + i];
1114
* As above, but transpose the matrix.
1117
load_transpose_matrix(GLfloat registers[][4], GLuint pos,
1118
const GLfloat mat[16])
1120
memcpy(registers[pos], mat, 16 * sizeof(GLfloat));
1125
* Load current vertex program's parameter registers with tracked
1126
* matrices (if NV program). This only needs to be done per
1127
* glBegin/glEnd, not per-vertex.
1130
_mesa_load_tracked_matrices(GLcontext *ctx)
1134
for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) {
1135
/* point 'mat' at source matrix */
1137
if (ctx->VertexProgram.TrackMatrix[i] == GL_MODELVIEW) {
1138
mat = ctx->ModelviewMatrixStack.Top;
1140
else if (ctx->VertexProgram.TrackMatrix[i] == GL_PROJECTION) {
1141
mat = ctx->ProjectionMatrixStack.Top;
1143
else if (ctx->VertexProgram.TrackMatrix[i] == GL_TEXTURE) {
1144
GLuint unit = MIN2(ctx->Texture.CurrentUnit,
1145
Elements(ctx->TextureMatrixStack) - 1);
1146
mat = ctx->TextureMatrixStack[unit].Top;
1148
else if (ctx->VertexProgram.TrackMatrix[i] == GL_COLOR) {
1149
mat = ctx->ColorMatrixStack.Top;
1151
else if (ctx->VertexProgram.TrackMatrix[i]==GL_MODELVIEW_PROJECTION_NV) {
1152
/* XXX verify the combined matrix is up to date */
1153
mat = &ctx->_ModelProjectMatrix;
1155
else if (ctx->VertexProgram.TrackMatrix[i] >= GL_MATRIX0_NV &&
1156
ctx->VertexProgram.TrackMatrix[i] <= GL_MATRIX7_NV) {
1157
GLuint n = ctx->VertexProgram.TrackMatrix[i] - GL_MATRIX0_NV;
1158
ASSERT(n < Elements(ctx->ProgramMatrixStack));
1159
mat = ctx->ProgramMatrixStack[n].Top;
1162
/* no matrix is tracked, but we leave the register values as-is */
1163
assert(ctx->VertexProgram.TrackMatrix[i] == GL_NONE);
1167
/* load the matrix values into sequential registers */
1168
if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) {
1169
load_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
1171
else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_INVERSE_NV) {
1172
_math_matrix_analyse(mat); /* update the inverse */
1173
ASSERT(!_math_matrix_is_dirty(mat));
1174
load_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
1176
else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_TRANSPOSE_NV) {
1177
load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
1180
assert(ctx->VertexProgram.TrackMatrixTransform[i]
1181
== GL_INVERSE_TRANSPOSE_NV);
1182
_math_matrix_analyse(mat); /* update the inverse */
1183
ASSERT(!_math_matrix_is_dirty(mat));
1184
load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);