~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

Viewing changes to src/mesa/shader/prog_statevars.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Mesa 3-D graphics library
3
 
 * Version:  7.1
4
 
 *
5
 
 * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
6
 
 *
7
 
 * Permission is hereby granted, free of charge, to any person obtaining a
8
 
 * copy of this software and associated documentation files (the "Software"),
9
 
 * to deal in the Software without restriction, including without limitation
10
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
 
 * and/or sell copies of the Software, and to permit persons to whom the
12
 
 * Software is furnished to do so, subject to the following conditions:
13
 
 *
14
 
 * The above copyright notice and this permission notice shall be included
15
 
 * in all copies or substantial portions of the Software.
16
 
 *
17
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18
 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
 
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21
 
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
 
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
 
 */
24
 
 
25
 
/**
26
 
 * \file 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/imports.h"
35
 
#include "main/macros.h"
36
 
#include "main/mtypes.h"
37
 
#include "prog_statevars.h"
38
 
#include "prog_parameter.h"
39
 
 
40
 
 
41
 
/**
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.
47
 
 */
48
 
static void
49
 
_mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
50
 
                  GLfloat *value)
51
 
{
52
 
   switch (state[0]) {
53
 
   case STATE_MATERIAL:
54
 
      {
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().
63
 
          */
64
 
         /* state[2] is the material attribute */
65
 
         switch (state[2]) {
66
 
         case STATE_AMBIENT:
67
 
            COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]);
68
 
            return;
69
 
         case STATE_DIFFUSE:
70
 
            COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]);
71
 
            return;
72
 
         case STATE_SPECULAR:
73
 
            COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]);
74
 
            return;
75
 
         case STATE_EMISSION:
76
 
            COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]);
77
 
            return;
78
 
         case STATE_SHININESS:
79
 
            value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0];
80
 
            value[1] = 0.0F;
81
 
            value[2] = 0.0F;
82
 
            value[3] = 1.0F;
83
 
            return;
84
 
         default:
85
 
            _mesa_problem(ctx, "Invalid material state in fetch_state");
86
 
            return;
87
 
         }
88
 
      }
89
 
   case STATE_LIGHT:
90
 
      {
91
 
         /* state[1] is the light number */
92
 
         const GLuint ln = (GLuint) state[1];
93
 
         /* state[2] is the light attribute */
94
 
         switch (state[2]) {
95
 
         case STATE_AMBIENT:
96
 
            COPY_4V(value, ctx->Light.Light[ln].Ambient);
97
 
            return;
98
 
         case STATE_DIFFUSE:
99
 
            COPY_4V(value, ctx->Light.Light[ln].Diffuse);
100
 
            return;
101
 
         case STATE_SPECULAR:
102
 
            COPY_4V(value, ctx->Light.Light[ln].Specular);
103
 
            return;
104
 
         case STATE_POSITION:
105
 
            COPY_4V(value, ctx->Light.Light[ln].EyePosition);
106
 
            return;
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;
112
 
            return;
113
 
         case STATE_SPOT_DIRECTION:
114
 
            COPY_3V(value, ctx->Light.Light[ln].SpotDirection);
115
 
            value[3] = ctx->Light.Light[ln]._CosCutoff;
116
 
            return;
117
 
         case STATE_SPOT_CUTOFF:
118
 
            value[0] = ctx->Light.Light[ln].SpotCutoff;
119
 
            return;
120
 
         case STATE_HALF_VECTOR:
121
 
            {
122
 
               static const GLfloat eye_z[] = {0, 0, 1};
123
 
               GLfloat p[3];
124
 
               /* Compute infinite half angle vector:
125
 
                *   halfVector = normalize(normalize(lightPos) + (0, 0, 1))
126
 
                * light.EyePosition.w should be 0 for infinite lights.
127
 
                */
128
 
               COPY_3V(p, ctx->Light.Light[ln].EyePosition);
129
 
               NORMALIZE_3FV(p);
130
 
               ADD_3V(value, p, eye_z);
131
 
               NORMALIZE_3FV(value);
132
 
               value[3] = 1.0;
133
 
            }
134
 
            return;
135
 
         default:
136
 
            _mesa_problem(ctx, "Invalid light state in fetch_state");
137
 
            return;
138
 
         }
139
 
      }
140
 
   case STATE_LIGHTMODEL_AMBIENT:
141
 
      COPY_4V(value, ctx->Light.Model.Ambient);
142
 
      return;
143
 
   case STATE_LIGHTMODEL_SCENECOLOR:
144
 
      if (state[1] == 0) {
145
 
         /* front */
146
 
         GLint i;
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];
151
 
         }
152
 
         value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
153
 
      }
154
 
      else {
155
 
         /* back */
156
 
         GLint i;
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];
161
 
         }
162
 
         value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
163
 
      }
164
 
      return;
165
 
   case STATE_LIGHTPROD:
166
 
      {
167
 
         const GLuint ln = (GLuint) state[1];
168
 
         const GLuint face = (GLuint) state[2];
169
 
         GLint i;
170
 
         ASSERT(face == 0 || face == 1);
171
 
         switch (state[3]) {
172
 
            case STATE_AMBIENT:
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];
176
 
               }
177
 
               /* [3] = material alpha */
178
 
               value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][3];
179
 
               return;
180
 
            case STATE_DIFFUSE:
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];
184
 
               }
185
 
               /* [3] = material alpha */
186
 
               value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
187
 
               return;
188
 
            case STATE_SPECULAR:
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];
192
 
               }
193
 
               /* [3] = material alpha */
194
 
               value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][3];
195
 
               return;
196
 
            default:
197
 
               _mesa_problem(ctx, "Invalid lightprod state in fetch_state");
198
 
               return;
199
 
         }
200
 
      }
201
 
   case STATE_TEXGEN:
202
 
      {
203
 
         /* state[1] is the texture unit */
204
 
         const GLuint unit = (GLuint) state[1];
205
 
         /* state[2] is the texgen attribute */
206
 
         switch (state[2]) {
207
 
         case STATE_TEXGEN_EYE_S:
208
 
            COPY_4V(value, ctx->Texture.Unit[unit].GenS.EyePlane);
209
 
            return;
210
 
         case STATE_TEXGEN_EYE_T:
211
 
            COPY_4V(value, ctx->Texture.Unit[unit].GenT.EyePlane);
212
 
            return;
213
 
         case STATE_TEXGEN_EYE_R:
214
 
            COPY_4V(value, ctx->Texture.Unit[unit].GenR.EyePlane);
215
 
            return;
216
 
         case STATE_TEXGEN_EYE_Q:
217
 
            COPY_4V(value, ctx->Texture.Unit[unit].GenQ.EyePlane);
218
 
            return;
219
 
         case STATE_TEXGEN_OBJECT_S:
220
 
            COPY_4V(value, ctx->Texture.Unit[unit].GenS.ObjectPlane);
221
 
            return;
222
 
         case STATE_TEXGEN_OBJECT_T:
223
 
            COPY_4V(value, ctx->Texture.Unit[unit].GenT.ObjectPlane);
224
 
            return;
225
 
         case STATE_TEXGEN_OBJECT_R:
226
 
            COPY_4V(value, ctx->Texture.Unit[unit].GenR.ObjectPlane);
227
 
            return;
228
 
         case STATE_TEXGEN_OBJECT_Q:
229
 
            COPY_4V(value, ctx->Texture.Unit[unit].GenQ.ObjectPlane);
230
 
            return;
231
 
         default:
232
 
            _mesa_problem(ctx, "Invalid texgen state in fetch_state");
233
 
            return;
234
 
         }
235
 
      }
236
 
   case STATE_TEXENV_COLOR:
237
 
      {
238
 
         /* state[1] is the texture unit */
239
 
         const GLuint unit = (GLuint) state[1];
240
 
         COPY_4V(value, ctx->Texture.Unit[unit].EnvColor);
241
 
      }
242
 
      return;
243
 
   case STATE_FOG_COLOR:
244
 
      COPY_4V(value, ctx->Fog.Color);
245
 
      return;
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));
252
 
      return;
253
 
   case STATE_CLIPPLANE:
254
 
      {
255
 
         const GLuint plane = (GLuint) state[1];
256
 
         COPY_4V(value, ctx->Transform.EyeUserPlane[plane]);
257
 
      }
258
 
      return;
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;
264
 
      return;
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];
269
 
      value[3] = 1.0F;
270
 
      return;
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:
277
 
      {
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];
289
 
         const GLfloat *m;
290
 
         GLuint row, i;
291
 
         ASSERT(firstRow >= 0);
292
 
         ASSERT(firstRow < 4);
293
 
         ASSERT(lastRow >= 0);
294
 
         ASSERT(lastRow < 4);
295
 
         if (mat == STATE_MODELVIEW_MATRIX) {
296
 
            matrix = ctx->ModelviewMatrixStack.Top;
297
 
         }
298
 
         else if (mat == STATE_PROJECTION_MATRIX) {
299
 
            matrix = ctx->ProjectionMatrixStack.Top;
300
 
         }
301
 
         else if (mat == STATE_MVP_MATRIX) {
302
 
            matrix = &ctx->_ModelProjectMatrix;
303
 
         }
304
 
         else if (mat == STATE_TEXTURE_MATRIX) {
305
 
            ASSERT(index < Elements(ctx->TextureMatrixStack));
306
 
            matrix = ctx->TextureMatrixStack[index].Top;
307
 
         }
308
 
         else if (mat == STATE_PROGRAM_MATRIX) {
309
 
            ASSERT(index < Elements(ctx->ProgramMatrixStack));
310
 
            matrix = ctx->ProgramMatrixStack[index].Top;
311
 
         }
312
 
         else if (mat == STATE_COLOR_MATRIX) {
313
 
            matrix = ctx->ColorMatrixStack.Top;
314
 
         }
315
 
         else {
316
 
            _mesa_problem(ctx, "Bad matrix name in _mesa_fetch_state()");
317
 
            return;
318
 
         }
319
 
         if (modifier == STATE_MATRIX_INVERSE ||
320
 
             modifier == STATE_MATRIX_INVTRANS) {
321
 
            /* Be sure inverse is up to date:
322
 
             */
323
 
            _math_matrix_alloc_inv( (GLmatrix *) matrix );
324
 
            _math_matrix_analyse( (GLmatrix*) matrix );
325
 
            m = matrix->inv;
326
 
         }
327
 
         else {
328
 
            m = matrix->m;
329
 
         }
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];
337
 
            }
338
 
         }
339
 
         else {
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];
345
 
            }
346
 
         }
347
 
      }
348
 
      return;
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 */
353
 
      value[3] = 1.0;
354
 
      return;
355
 
   case STATE_FRAGMENT_PROGRAM:
356
 
      {
357
 
         /* state[1] = {STATE_ENV, STATE_LOCAL} */
358
 
         /* state[2] = parameter index          */
359
 
         const int idx = (int) state[2];
360
 
         switch (state[1]) {
361
 
            case STATE_ENV:
362
 
               COPY_4V(value, ctx->FragmentProgram.Parameters[idx]);
363
 
               return;
364
 
            case STATE_LOCAL:
365
 
               COPY_4V(value, ctx->FragmentProgram.Current->Base.LocalParams[idx]);
366
 
               return;
367
 
            default:
368
 
               _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
369
 
               return;
370
 
         }
371
 
      }
372
 
      return;
373
 
 
374
 
   case STATE_VERTEX_PROGRAM:
375
 
      {
376
 
         /* state[1] = {STATE_ENV, STATE_LOCAL} */
377
 
         /* state[2] = parameter index          */
378
 
         const int idx = (int) state[2];
379
 
         switch (state[1]) {
380
 
            case STATE_ENV:
381
 
               COPY_4V(value, ctx->VertexProgram.Parameters[idx]);
382
 
               return;
383
 
            case STATE_LOCAL:
384
 
               COPY_4V(value, ctx->VertexProgram.Current->Base.LocalParams[idx]);
385
 
               return;
386
 
            default:
387
 
               _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
388
 
               return;
389
 
         }
390
 
      }
391
 
      return;
392
 
 
393
 
   case STATE_NORMAL_SCALE:
394
 
      ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1);
395
 
      return;
396
 
 
397
 
   case STATE_INTERNAL:
398
 
      switch (state[1]) {
399
 
      case STATE_CURRENT_ATTRIB:
400
 
         {
401
 
            const GLuint idx = (GLuint) state[2];
402
 
            COPY_4V(value, ctx->Current.Attrib[idx]);
403
 
         }
404
 
         return;
405
 
 
406
 
      case STATE_NORMAL_SCALE:
407
 
         ASSIGN_4V(value, 
408
 
                   ctx->_ModelViewInvScale, 
409
 
                   ctx->_ModelViewInvScale, 
410
 
                   ctx->_ModelViewInvScale, 
411
 
                   1);
412
 
         return;
413
 
 
414
 
      case STATE_TEXRECT_SCALE:
415
 
         /* Value = { 1/texWidth, 1/texHeight, 0, 1 }.
416
 
          * Used to convert unnormalized texcoords to normalized texcoords.
417
 
          */
418
 
         {
419
 
            const int unit = (int) state[2];
420
 
            const struct gl_texture_object *texObj
421
 
               = ctx->Texture.Unit[unit]._Current;
422
 
            if (texObj) {
423
 
               struct gl_texture_image *texImage = texObj->Image[0][0];
424
 
               ASSIGN_4V(value,
425
 
                         (GLfloat) (1.0 / texImage->Width),
426
 
                         (GLfloat) (1.0 / texImage->Height),
427
 
                         0.0f, 1.0f);
428
 
            }
429
 
         }
430
 
         return;
431
 
 
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
436
 
          * single MAD.
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)
440
 
          */
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);
446
 
         return;
447
 
 
448
 
      case STATE_POINT_SIZE_CLAMPED:
449
 
         {
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.
459
 
            */
460
 
            GLfloat minImplSize;
461
 
            GLfloat maxImplSize;
462
 
            if (ctx->Point.PointSprite) {
463
 
               minImplSize = ctx->Const.MinPointSizeAA;
464
 
               maxImplSize = ctx->Const.MaxPointSize;
465
 
            }
466
 
            else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) {
467
 
               minImplSize = ctx->Const.MinPointSizeAA;
468
 
               maxImplSize = ctx->Const.MaxPointSizeAA;
469
 
            }
470
 
            else {
471
 
               minImplSize = ctx->Const.MinPointSize;
472
 
               maxImplSize = ctx->Const.MaxPointSize;
473
 
            }
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;
478
 
         }
479
 
         return;
480
 
      case STATE_POINT_SIZE_IMPL_CLAMP:
481
 
         {
482
 
           /* for implementation clamp only in vs */
483
 
            GLfloat minImplSize;
484
 
            GLfloat maxImplSize;
485
 
            if (ctx->Point.PointSprite) {
486
 
               minImplSize = ctx->Const.MinPointSizeAA;
487
 
               maxImplSize = ctx->Const.MaxPointSize;
488
 
            }
489
 
            else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) {
490
 
               minImplSize = ctx->Const.MinPointSizeAA;
491
 
               maxImplSize = ctx->Const.MaxPointSizeAA;
492
 
            }
493
 
            else {
494
 
               minImplSize = ctx->Const.MinPointSize;
495
 
               maxImplSize = ctx->Const.MaxPointSize;
496
 
            }
497
 
            value[0] = ctx->Point.Size;
498
 
            value[1] = minImplSize;
499
 
            value[2] = maxImplSize;
500
 
            value[3] = ctx->Point.Threshold;
501
 
         }
502
 
         return;
503
 
      case STATE_LIGHT_SPOT_DIR_NORMALIZED:
504
 
         {
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;
510
 
         }
511
 
         return;
512
 
 
513
 
      case STATE_LIGHT_POSITION:
514
 
         {
515
 
            const GLuint ln = (GLuint) state[2];
516
 
            COPY_4V(value, ctx->Light.Light[ln]._Position);
517
 
         }
518
 
         return;
519
 
 
520
 
      case STATE_LIGHT_POSITION_NORMALIZED:
521
 
         {
522
 
            const GLuint ln = (GLuint) state[2];
523
 
            COPY_4V(value, ctx->Light.Light[ln]._Position);
524
 
            NORMALIZE_3FV( value );
525
 
         }
526
 
         return;
527
 
 
528
 
      case STATE_LIGHT_HALF_VECTOR:
529
 
         {
530
 
            const GLuint ln = (GLuint) state[2];
531
 
            GLfloat p[3];
532
 
            /* Compute infinite half angle vector:
533
 
             *   halfVector = normalize(normalize(lightPos) + (0, 0, 1))
534
 
             * light.EyePosition.w should be 0 for infinite lights.
535
 
             */
536
 
            COPY_3V(p, ctx->Light.Light[ln]._Position);
537
 
            NORMALIZE_3FV(p);
538
 
            ADD_3V(value, p, ctx->_EyeZDir);
539
 
            NORMALIZE_3FV(value);
540
 
            value[3] = 1.0;
541
 
         }
542
 
         return;
543
 
 
544
 
      case STATE_PT_SCALE:
545
 
         value[0] = ctx->Pixel.RedScale;
546
 
         value[1] = ctx->Pixel.GreenScale;
547
 
         value[2] = ctx->Pixel.BlueScale;
548
 
         value[3] = ctx->Pixel.AlphaScale;
549
 
         return;
550
 
 
551
 
      case STATE_PT_BIAS:
552
 
         value[0] = ctx->Pixel.RedBias;
553
 
         value[1] = ctx->Pixel.GreenBias;
554
 
         value[2] = ctx->Pixel.BlueBias;
555
 
         value[3] = ctx->Pixel.AlphaBias;
556
 
         return;
557
 
 
558
 
      case STATE_PCM_SCALE:
559
 
         COPY_4V(value, ctx->Pixel.PostColorMatrixScale);
560
 
         return;
561
 
 
562
 
      case STATE_PCM_BIAS:
563
 
         COPY_4V(value, ctx->Pixel.PostColorMatrixBias);
564
 
         return;
565
 
 
566
 
      case STATE_SHADOW_AMBIENT:
567
 
         {
568
 
            const int unit = (int) state[2];
569
 
            const struct gl_texture_object *texObj
570
 
               = ctx->Texture.Unit[unit]._Current;
571
 
            if (texObj) {
572
 
               value[0] =
573
 
               value[1] =
574
 
               value[2] =
575
 
               value[3] = texObj->CompareFailValue;
576
 
            }
577
 
         }
578
 
         return;
579
 
 
580
 
      case STATE_FB_SIZE:
581
 
         value[0] = (GLfloat) (ctx->DrawBuffer->Width - 1);
582
 
         value[1] = (GLfloat) (ctx->DrawBuffer->Height - 1);
583
 
         value[2] = 0.0F;
584
 
         value[3] = 0.0F;
585
 
         return;
586
 
 
587
 
      case STATE_ROT_MATRIX_0:
588
 
         {
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];
593
 
            value[2] = 0.0;
594
 
            value[3] = 0.0;
595
 
         }
596
 
         return;
597
 
 
598
 
      case STATE_ROT_MATRIX_1:
599
 
         {
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];
604
 
            value[2] = 0.0;
605
 
            value[3] = 0.0;
606
 
         }
607
 
         return;
608
 
 
609
 
      /* XXX: make sure new tokens added here are also handled in the 
610
 
       * _mesa_program_state_flags() switch, below.
611
 
       */
612
 
      default:
613
 
         /* Unknown state indexes are silently ignored here.
614
 
          * Drivers may do something special.
615
 
          */
616
 
         return;
617
 
      }
618
 
      return;
619
 
 
620
 
   default:
621
 
      _mesa_problem(ctx, "Invalid state in _mesa_fetch_state");
622
 
      return;
623
 
   }
624
 
}
625
 
 
626
 
 
627
 
/**
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.
633
 
 */
634
 
GLbitfield
635
 
_mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
636
 
{
637
 
   switch (state[0]) {
638
 
   case STATE_MATERIAL:
639
 
   case STATE_LIGHT:
640
 
   case STATE_LIGHTMODEL_AMBIENT:
641
 
   case STATE_LIGHTMODEL_SCENECOLOR:
642
 
   case STATE_LIGHTPROD:
643
 
      return _NEW_LIGHT;
644
 
 
645
 
   case STATE_TEXGEN:
646
 
   case STATE_TEXENV_COLOR:
647
 
      return _NEW_TEXTURE;
648
 
 
649
 
   case STATE_FOG_COLOR:
650
 
   case STATE_FOG_PARAMS:
651
 
      return _NEW_FOG;
652
 
 
653
 
   case STATE_CLIPPLANE:
654
 
      return _NEW_TRANSFORM;
655
 
 
656
 
   case STATE_POINT_SIZE:
657
 
   case STATE_POINT_ATTENUATION:
658
 
      return _NEW_POINT;
659
 
 
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;
672
 
 
673
 
   case STATE_DEPTH_RANGE:
674
 
      return _NEW_VIEWPORT;
675
 
 
676
 
   case STATE_FRAGMENT_PROGRAM:
677
 
   case STATE_VERTEX_PROGRAM:
678
 
      return _NEW_PROGRAM;
679
 
 
680
 
   case STATE_NORMAL_SCALE:
681
 
      return _NEW_MODELVIEW;
682
 
 
683
 
   case STATE_INTERNAL:
684
 
      switch (state[1]) {
685
 
      case STATE_CURRENT_ATTRIB:
686
 
         return _NEW_CURRENT_ATTRIB;
687
 
 
688
 
      case STATE_NORMAL_SCALE:
689
 
         return _NEW_MODELVIEW;
690
 
 
691
 
      case STATE_TEXRECT_SCALE:
692
 
      case STATE_SHADOW_AMBIENT:
693
 
      case STATE_ROT_MATRIX_0:
694
 
      case STATE_ROT_MATRIX_1:
695
 
         return _NEW_TEXTURE;
696
 
      case STATE_FOG_PARAMS_OPTIMIZED:
697
 
         return _NEW_FOG;
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:
705
 
         return _NEW_LIGHT;
706
 
 
707
 
      case STATE_PT_SCALE:
708
 
      case STATE_PT_BIAS:
709
 
      case STATE_PCM_SCALE:
710
 
      case STATE_PCM_BIAS:
711
 
         return _NEW_PIXEL;
712
 
 
713
 
      case STATE_FB_SIZE:
714
 
         return _NEW_BUFFERS;
715
 
 
716
 
      default:
717
 
         /* unknown state indexes are silently ignored and
718
 
         *  no flag set, since it is handled by the driver.
719
 
         */
720
 
         return 0;
721
 
      }
722
 
 
723
 
   default:
724
 
      _mesa_problem(NULL, "unexpected state[0] in make_state_flags()");
725
 
      return 0;
726
 
   }
727
 
}
728
 
 
729
 
 
730
 
static void
731
 
append(char *dst, const char *src)
732
 
{
733
 
   while (*dst)
734
 
      dst++;
735
 
   while (*src)
736
 
     *dst++ = *src++;
737
 
   *dst = 0;
738
 
}
739
 
 
740
 
 
741
 
/**
742
 
 * Convert token 'k' to a string, append it onto 'dst' string.
743
 
 */
744
 
static void
745
 
append_token(char *dst, gl_state_index k)
746
 
{
747
 
   switch (k) {
748
 
   case STATE_MATERIAL:
749
 
      append(dst, "material");
750
 
      break;
751
 
   case STATE_LIGHT:
752
 
      append(dst, "light");
753
 
      break;
754
 
   case STATE_LIGHTMODEL_AMBIENT:
755
 
      append(dst, "lightmodel.ambient");
756
 
      break;
757
 
   case STATE_LIGHTMODEL_SCENECOLOR:
758
 
      break;
759
 
   case STATE_LIGHTPROD:
760
 
      append(dst, "lightprod");
761
 
      break;
762
 
   case STATE_TEXGEN:
763
 
      append(dst, "texgen");
764
 
      break;
765
 
   case STATE_FOG_COLOR:
766
 
      append(dst, "fog.color");
767
 
      break;
768
 
   case STATE_FOG_PARAMS:
769
 
      append(dst, "fog.params");
770
 
      break;
771
 
   case STATE_CLIPPLANE:
772
 
      append(dst, "clip");
773
 
      break;
774
 
   case STATE_POINT_SIZE:
775
 
      append(dst, "point.size");
776
 
      break;
777
 
   case STATE_POINT_ATTENUATION:
778
 
      append(dst, "point.attenuation");
779
 
      break;
780
 
   case STATE_MODELVIEW_MATRIX:
781
 
      append(dst, "matrix.modelview");
782
 
      break;
783
 
   case STATE_PROJECTION_MATRIX:
784
 
      append(dst, "matrix.projection");
785
 
      break;
786
 
   case STATE_MVP_MATRIX:
787
 
      append(dst, "matrix.mvp");
788
 
      break;
789
 
   case STATE_TEXTURE_MATRIX:
790
 
      append(dst, "matrix.texture");
791
 
      break;
792
 
   case STATE_PROGRAM_MATRIX:
793
 
      append(dst, "matrix.program");
794
 
      break;
795
 
   case STATE_COLOR_MATRIX:
796
 
      append(dst, "matrix.color");
797
 
      break;
798
 
   case STATE_MATRIX_INVERSE:
799
 
      append(dst, ".inverse");
800
 
      break;
801
 
   case STATE_MATRIX_TRANSPOSE:
802
 
      append(dst, ".transpose");
803
 
      break;
804
 
   case STATE_MATRIX_INVTRANS:
805
 
      append(dst, ".invtrans");
806
 
      break;
807
 
   case STATE_AMBIENT:
808
 
      append(dst, ".ambient");
809
 
      break;
810
 
   case STATE_DIFFUSE:
811
 
      append(dst, ".diffuse");
812
 
      break;
813
 
   case STATE_SPECULAR:
814
 
      append(dst, ".specular");
815
 
      break;
816
 
   case STATE_EMISSION:
817
 
      append(dst, ".emission");
818
 
      break;
819
 
   case STATE_SHININESS:
820
 
      append(dst, "lshininess");
821
 
      break;
822
 
   case STATE_HALF_VECTOR:
823
 
      append(dst, ".half");
824
 
      break;
825
 
   case STATE_POSITION:
826
 
      append(dst, ".position");
827
 
      break;
828
 
   case STATE_ATTENUATION:
829
 
      append(dst, ".attenuation");
830
 
      break;
831
 
   case STATE_SPOT_DIRECTION:
832
 
      append(dst, ".spot.direction");
833
 
      break;
834
 
   case STATE_SPOT_CUTOFF:
835
 
      append(dst, ".spot.cutoff");
836
 
      break;
837
 
   case STATE_TEXGEN_EYE_S:
838
 
      append(dst, ".eye.s");
839
 
      break;
840
 
   case STATE_TEXGEN_EYE_T:
841
 
      append(dst, ".eye.t");
842
 
      break;
843
 
   case STATE_TEXGEN_EYE_R:
844
 
      append(dst, ".eye.r");
845
 
      break;
846
 
   case STATE_TEXGEN_EYE_Q:
847
 
      append(dst, ".eye.q");
848
 
      break;
849
 
   case STATE_TEXGEN_OBJECT_S:
850
 
      append(dst, ".object.s");
851
 
      break;
852
 
   case STATE_TEXGEN_OBJECT_T:
853
 
      append(dst, ".object.t");
854
 
      break;
855
 
   case STATE_TEXGEN_OBJECT_R:
856
 
      append(dst, ".object.r");
857
 
      break;
858
 
   case STATE_TEXGEN_OBJECT_Q:
859
 
      append(dst, ".object.q");
860
 
      break;
861
 
   case STATE_TEXENV_COLOR:
862
 
      append(dst, "texenv");
863
 
      break;
864
 
   case STATE_DEPTH_RANGE:
865
 
      append(dst, "depth.range");
866
 
      break;
867
 
   case STATE_VERTEX_PROGRAM:
868
 
   case STATE_FRAGMENT_PROGRAM:
869
 
      break;
870
 
   case STATE_ENV:
871
 
      append(dst, "env");
872
 
      break;
873
 
   case STATE_LOCAL:
874
 
      append(dst, "local");
875
 
      break;
876
 
   /* BEGIN internal state vars */
877
 
   case STATE_INTERNAL:
878
 
      append(dst, ".internal.");
879
 
      break;
880
 
   case STATE_CURRENT_ATTRIB:
881
 
      append(dst, "current");
882
 
      break;
883
 
   case STATE_NORMAL_SCALE:
884
 
      append(dst, "normalScale");
885
 
      break;
886
 
   case STATE_TEXRECT_SCALE:
887
 
      append(dst, "texrectScale");
888
 
      break;
889
 
   case STATE_FOG_PARAMS_OPTIMIZED:
890
 
      append(dst, "fogParamsOptimized");
891
 
      break;
892
 
   case STATE_POINT_SIZE_CLAMPED:
893
 
      append(dst, "pointSizeClamped");
894
 
      break;
895
 
   case STATE_POINT_SIZE_IMPL_CLAMP:
896
 
      append(dst, "pointSizeImplClamp");
897
 
      break;
898
 
   case STATE_LIGHT_SPOT_DIR_NORMALIZED:
899
 
      append(dst, "lightSpotDirNormalized");
900
 
      break;
901
 
   case STATE_LIGHT_POSITION:
902
 
      append(dst, "lightPosition");
903
 
      break;
904
 
   case STATE_LIGHT_POSITION_NORMALIZED:
905
 
      append(dst, "light.position.normalized");
906
 
      break;
907
 
   case STATE_LIGHT_HALF_VECTOR:
908
 
      append(dst, "lightHalfVector");
909
 
      break;
910
 
   case STATE_PT_SCALE:
911
 
      append(dst, "PTscale");
912
 
      break;
913
 
   case STATE_PT_BIAS:
914
 
      append(dst, "PTbias");
915
 
      break;
916
 
   case STATE_PCM_SCALE:
917
 
      append(dst, "PCMscale");
918
 
      break;
919
 
   case STATE_PCM_BIAS:
920
 
      append(dst, "PCMbias");
921
 
      break;
922
 
   case STATE_SHADOW_AMBIENT:
923
 
      append(dst, "CompareFailValue");
924
 
      break;
925
 
   case STATE_FB_SIZE:
926
 
      append(dst, "FbSize");
927
 
      break;
928
 
   case STATE_ROT_MATRIX_0:
929
 
      append(dst, "rotMatrixRow0");
930
 
      break;
931
 
   case STATE_ROT_MATRIX_1:
932
 
      append(dst, "rotMatrixRow1");
933
 
      break;
934
 
   default:
935
 
      /* probably STATE_INTERNAL_DRIVER+i (driver private state) */
936
 
      append(dst, "driverState");
937
 
   }
938
 
}
939
 
 
940
 
static void
941
 
append_face(char *dst, GLint face)
942
 
{
943
 
   if (face == 0)
944
 
      append(dst, "front.");
945
 
   else
946
 
      append(dst, "back.");
947
 
}
948
 
 
949
 
static void
950
 
append_index(char *dst, GLint index)
951
 
{
952
 
   char s[20];
953
 
   sprintf(s, "[%d]", index);
954
 
   append(dst, s);
955
 
}
956
 
 
957
 
/**
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.
961
 
 */
962
 
char *
963
 
_mesa_program_state_string(const gl_state_index state[STATE_LENGTH])
964
 
{
965
 
   char str[1000] = "";
966
 
   char tmp[30];
967
 
 
968
 
   append(str, "state.");
969
 
   append_token(str, state[0]);
970
 
 
971
 
   switch (state[0]) {
972
 
   case STATE_MATERIAL:
973
 
      append_face(str, state[1]);
974
 
      append_token(str, state[2]);
975
 
      break;
976
 
   case STATE_LIGHT:
977
 
      append_index(str, state[1]); /* light number [i]. */
978
 
      append_token(str, state[2]); /* coefficients */
979
 
      break;
980
 
   case STATE_LIGHTMODEL_AMBIENT:
981
 
      append(str, "lightmodel.ambient");
982
 
      break;
983
 
   case STATE_LIGHTMODEL_SCENECOLOR:
984
 
      if (state[1] == 0) {
985
 
         append(str, "lightmodel.front.scenecolor");
986
 
      }
987
 
      else {
988
 
         append(str, "lightmodel.back.scenecolor");
989
 
      }
990
 
      break;
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]);
995
 
      break;
996
 
   case STATE_TEXGEN:
997
 
      append_index(str, state[1]); /* tex unit [i] */
998
 
      append_token(str, state[2]); /* plane coef */
999
 
      break;
1000
 
   case STATE_TEXENV_COLOR:
1001
 
      append_index(str, state[1]); /* tex unit [i] */
1002
 
      append(str, "color");
1003
 
      break;
1004
 
   case STATE_CLIPPLANE:
1005
 
      append_index(str, state[1]); /* plane [i] */
1006
 
      append(str, ".plane");
1007
 
      break;
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:
1014
 
      {
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];
1025
 
         if (index ||
1026
 
             mat == STATE_TEXTURE_MATRIX ||
1027
 
             mat == STATE_PROGRAM_MATRIX)
1028
 
            append_index(str, index);
1029
 
         if (modifier)
1030
 
            append_token(str, modifier);
1031
 
         if (firstRow == lastRow)
1032
 
            sprintf(tmp, ".row[%d]", firstRow);
1033
 
         else
1034
 
            sprintf(tmp, ".row[%d..%d]", firstRow, lastRow);
1035
 
         append(str, tmp);
1036
 
      }
1037
 
      break;
1038
 
   case STATE_POINT_SIZE:
1039
 
      break;
1040
 
   case STATE_POINT_ATTENUATION:
1041
 
      break;
1042
 
   case STATE_FOG_PARAMS:
1043
 
      break;
1044
 
   case STATE_FOG_COLOR:
1045
 
      break;
1046
 
   case STATE_DEPTH_RANGE:
1047
 
      break;
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]);
1054
 
      break;
1055
 
   case STATE_INTERNAL:
1056
 
      append_token(str, state[1]);
1057
 
      if (state[1] == STATE_CURRENT_ATTRIB)
1058
 
         append_index(str, state[2]);
1059
 
       break;
1060
 
   default:
1061
 
      _mesa_problem(NULL, "Invalid state in _mesa_program_state_string");
1062
 
      break;
1063
 
   }
1064
 
 
1065
 
   return _mesa_strdup(str);
1066
 
}
1067
 
 
1068
 
 
1069
 
/**
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.
1074
 
 */
1075
 
void
1076
 
_mesa_load_state_parameters(GLcontext *ctx,
1077
 
                            struct gl_program_parameter_list *paramList)
1078
 
{
1079
 
   GLuint i;
1080
 
 
1081
 
   if (!paramList)
1082
 
      return;
1083
 
 
1084
 
   /*assert(ctx->Driver.NeedFlush == 0);*/
1085
 
 
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]);
1091
 
      }
1092
 
   }
1093
 
}
1094
 
 
1095
 
 
1096
 
/**
1097
 
 * Copy the 16 elements of a matrix into four consecutive program
1098
 
 * registers starting at 'pos'.
1099
 
 */
1100
 
static void
1101
 
load_matrix(GLfloat registers[][4], GLuint pos, const GLfloat mat[16])
1102
 
{
1103
 
   GLuint i;
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];
1109
 
   }
1110
 
}
1111
 
 
1112
 
 
1113
 
/**
1114
 
 * As above, but transpose the matrix.
1115
 
 */
1116
 
static void
1117
 
load_transpose_matrix(GLfloat registers[][4], GLuint pos,
1118
 
                      const GLfloat mat[16])
1119
 
{
1120
 
   memcpy(registers[pos], mat, 16 * sizeof(GLfloat));
1121
 
}
1122
 
 
1123
 
 
1124
 
/**
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.
1128
 
 */
1129
 
void
1130
 
_mesa_load_tracked_matrices(GLcontext *ctx)
1131
 
{
1132
 
   GLuint i;
1133
 
 
1134
 
   for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) {
1135
 
      /* point 'mat' at source matrix */
1136
 
      GLmatrix *mat;
1137
 
      if (ctx->VertexProgram.TrackMatrix[i] == GL_MODELVIEW) {
1138
 
         mat = ctx->ModelviewMatrixStack.Top;
1139
 
      }
1140
 
      else if (ctx->VertexProgram.TrackMatrix[i] == GL_PROJECTION) {
1141
 
         mat = ctx->ProjectionMatrixStack.Top;
1142
 
      }
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;
1147
 
      }
1148
 
      else if (ctx->VertexProgram.TrackMatrix[i] == GL_COLOR) {
1149
 
         mat = ctx->ColorMatrixStack.Top;
1150
 
      }
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;
1154
 
      }
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;
1160
 
      }
1161
 
      else {
1162
 
         /* no matrix is tracked, but we leave the register values as-is */
1163
 
         assert(ctx->VertexProgram.TrackMatrix[i] == GL_NONE);
1164
 
         continue;
1165
 
      }
1166
 
 
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);
1170
 
      }
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);
1175
 
      }
1176
 
      else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_TRANSPOSE_NV) {
1177
 
         load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
1178
 
      }
1179
 
      else {
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);
1185
 
      }
1186
 
   }
1187
 
}