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

« back to all changes in this revision

Viewing changes to src/mesa/program/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_NORMAL_SCALE:
 
1056
      break;
 
1057
   case STATE_INTERNAL:
 
1058
      append_token(str, state[1]);
 
1059
      if (state[1] == STATE_CURRENT_ATTRIB)
 
1060
         append_index(str, state[2]);
 
1061
       break;
 
1062
   default:
 
1063
      _mesa_problem(NULL, "Invalid state in _mesa_program_state_string");
 
1064
      break;
 
1065
   }
 
1066
 
 
1067
   return _mesa_strdup(str);
 
1068
}
 
1069
 
 
1070
 
 
1071
/**
 
1072
 * Loop over all the parameters in a parameter list.  If the parameter
 
1073
 * is a GL state reference, look up the current value of that state
 
1074
 * variable and put it into the parameter's Value[4] array.
 
1075
 * This would be called at glBegin time when using a fragment program.
 
1076
 */
 
1077
void
 
1078
_mesa_load_state_parameters(GLcontext *ctx,
 
1079
                            struct gl_program_parameter_list *paramList)
 
1080
{
 
1081
   GLuint i;
 
1082
 
 
1083
   if (!paramList)
 
1084
      return;
 
1085
 
 
1086
   /*assert(ctx->Driver.NeedFlush == 0);*/
 
1087
 
 
1088
   for (i = 0; i < paramList->NumParameters; i++) {
 
1089
      if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) {
 
1090
         _mesa_fetch_state(ctx,
 
1091
                           (gl_state_index *) paramList->Parameters[i].StateIndexes,
 
1092
                           paramList->ParameterValues[i]);
 
1093
      }
 
1094
   }
 
1095
}
 
1096
 
 
1097
 
 
1098
/**
 
1099
 * Copy the 16 elements of a matrix into four consecutive program
 
1100
 * registers starting at 'pos'.
 
1101
 */
 
1102
static void
 
1103
load_matrix(GLfloat registers[][4], GLuint pos, const GLfloat mat[16])
 
1104
{
 
1105
   GLuint i;
 
1106
   for (i = 0; i < 4; i++) {
 
1107
      registers[pos + i][0] = mat[0 + i];
 
1108
      registers[pos + i][1] = mat[4 + i];
 
1109
      registers[pos + i][2] = mat[8 + i];
 
1110
      registers[pos + i][3] = mat[12 + i];
 
1111
   }
 
1112
}
 
1113
 
 
1114
 
 
1115
/**
 
1116
 * As above, but transpose the matrix.
 
1117
 */
 
1118
static void
 
1119
load_transpose_matrix(GLfloat registers[][4], GLuint pos,
 
1120
                      const GLfloat mat[16])
 
1121
{
 
1122
   memcpy(registers[pos], mat, 16 * sizeof(GLfloat));
 
1123
}
 
1124
 
 
1125
 
 
1126
/**
 
1127
 * Load current vertex program's parameter registers with tracked
 
1128
 * matrices (if NV program).  This only needs to be done per
 
1129
 * glBegin/glEnd, not per-vertex.
 
1130
 */
 
1131
void
 
1132
_mesa_load_tracked_matrices(GLcontext *ctx)
 
1133
{
 
1134
   GLuint i;
 
1135
 
 
1136
   for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) {
 
1137
      /* point 'mat' at source matrix */
 
1138
      GLmatrix *mat;
 
1139
      if (ctx->VertexProgram.TrackMatrix[i] == GL_MODELVIEW) {
 
1140
         mat = ctx->ModelviewMatrixStack.Top;
 
1141
      }
 
1142
      else if (ctx->VertexProgram.TrackMatrix[i] == GL_PROJECTION) {
 
1143
         mat = ctx->ProjectionMatrixStack.Top;
 
1144
      }
 
1145
      else if (ctx->VertexProgram.TrackMatrix[i] == GL_TEXTURE) {
 
1146
         GLuint unit = MIN2(ctx->Texture.CurrentUnit,
 
1147
                            Elements(ctx->TextureMatrixStack) - 1);
 
1148
         mat = ctx->TextureMatrixStack[unit].Top;
 
1149
      }
 
1150
      else if (ctx->VertexProgram.TrackMatrix[i] == GL_COLOR) {
 
1151
         mat = ctx->ColorMatrixStack.Top;
 
1152
      }
 
1153
      else if (ctx->VertexProgram.TrackMatrix[i]==GL_MODELVIEW_PROJECTION_NV) {
 
1154
         /* XXX verify the combined matrix is up to date */
 
1155
         mat = &ctx->_ModelProjectMatrix;
 
1156
      }
 
1157
      else if (ctx->VertexProgram.TrackMatrix[i] >= GL_MATRIX0_NV &&
 
1158
               ctx->VertexProgram.TrackMatrix[i] <= GL_MATRIX7_NV) {
 
1159
         GLuint n = ctx->VertexProgram.TrackMatrix[i] - GL_MATRIX0_NV;
 
1160
         ASSERT(n < Elements(ctx->ProgramMatrixStack));
 
1161
         mat = ctx->ProgramMatrixStack[n].Top;
 
1162
      }
 
1163
      else {
 
1164
         /* no matrix is tracked, but we leave the register values as-is */
 
1165
         assert(ctx->VertexProgram.TrackMatrix[i] == GL_NONE);
 
1166
         continue;
 
1167
      }
 
1168
 
 
1169
      /* load the matrix values into sequential registers */
 
1170
      if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) {
 
1171
         load_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
 
1172
      }
 
1173
      else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_INVERSE_NV) {
 
1174
         _math_matrix_analyse(mat); /* update the inverse */
 
1175
         ASSERT(!_math_matrix_is_dirty(mat));
 
1176
         load_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
 
1177
      }
 
1178
      else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_TRANSPOSE_NV) {
 
1179
         load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
 
1180
      }
 
1181
      else {
 
1182
         assert(ctx->VertexProgram.TrackMatrixTransform[i]
 
1183
                == GL_INVERSE_TRANSPOSE_NV);
 
1184
         _math_matrix_analyse(mat); /* update the inverse */
 
1185
         ASSERT(!_math_matrix_is_dirty(mat));
 
1186
         load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
 
1187
      }
 
1188
   }
 
1189
}