Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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