Subversion Repositories Kolibri OS

Rev

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