Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
  5.  * Copyright (C) 2009-2010  VMware, Inc.  All Rights Reserved.
  6.  * Copyright © 2010 Intel Corporation
  7.  *
  8.  * Permission is hereby granted, free of charge, to any person obtaining a
  9.  * copy of this software and associated documentation files (the "Software"),
  10.  * to deal in the Software without restriction, including without limitation
  11.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  12.  * and/or sell copies of the Software, and to permit persons to whom the
  13.  * Software is furnished to do so, subject to the following conditions:
  14.  *
  15.  * The above copyright notice and this permission notice shall be included
  16.  * in all copies or substantial portions of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  21.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  22.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  23.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24.  */
  25.  
  26. /**
  27.  * \file uniforms.c
  28.  * Functions related to GLSL uniform variables.
  29.  * \author Brian Paul
  30.  */
  31.  
  32. /**
  33.  * XXX things to do:
  34.  * 1. Check that the right error code is generated for all _mesa_error() calls.
  35.  * 2. Insert FLUSH_VERTICES calls in various places
  36.  */
  37.  
  38.  
  39. #include "main/glheader.h"
  40. #include "main/context.h"
  41. #include "main/dispatch.h"
  42. #include "main/shaderapi.h"
  43. #include "main/shaderobj.h"
  44. #include "main/uniforms.h"
  45. #include "program/prog_parameter.h"
  46. #include "program/prog_statevars.h"
  47. #include "program/prog_uniform.h"
  48. #include "program/prog_instruction.h"
  49.  
  50.  
  51. static GLenum
  52. base_uniform_type(GLenum type)
  53. {
  54.    switch (type) {
  55. #if 0 /* not needed, for now */
  56.    case GL_BOOL:
  57.    case GL_BOOL_VEC2:
  58.    case GL_BOOL_VEC3:
  59.    case GL_BOOL_VEC4:
  60.       return GL_BOOL;
  61. #endif
  62.    case GL_FLOAT:
  63.    case GL_FLOAT_VEC2:
  64.    case GL_FLOAT_VEC3:
  65.    case GL_FLOAT_VEC4:
  66.       return GL_FLOAT;
  67.    case GL_UNSIGNED_INT:
  68.    case GL_UNSIGNED_INT_VEC2:
  69.    case GL_UNSIGNED_INT_VEC3:
  70.    case GL_UNSIGNED_INT_VEC4:
  71.       return GL_UNSIGNED_INT;
  72.    case GL_INT:
  73.    case GL_INT_VEC2:
  74.    case GL_INT_VEC3:
  75.    case GL_INT_VEC4:
  76.       return GL_INT;
  77.    default:
  78.       _mesa_problem(NULL, "Invalid type in base_uniform_type()");
  79.       return GL_FLOAT;
  80.    }
  81. }
  82.  
  83. static struct gl_builtin_uniform_element gl_DepthRange_elements[] = {
  84.    {"near", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX},
  85.    {"far", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_YYYY},
  86.    {"diff", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_ZZZZ},
  87. };
  88.  
  89. static struct gl_builtin_uniform_element gl_ClipPlane_elements[] = {
  90.    {NULL, {STATE_CLIPPLANE, 0, 0}, SWIZZLE_XYZW}
  91. };
  92.  
  93. static struct gl_builtin_uniform_element gl_Point_elements[] = {
  94.    {"size", {STATE_POINT_SIZE}, SWIZZLE_XXXX},
  95.    {"sizeMin", {STATE_POINT_SIZE}, SWIZZLE_YYYY},
  96.    {"sizeMax", {STATE_POINT_SIZE}, SWIZZLE_ZZZZ},
  97.    {"fadeThresholdSize", {STATE_POINT_SIZE}, SWIZZLE_WWWW},
  98.    {"distanceConstantAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_XXXX},
  99.    {"distanceLinearAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_YYYY},
  100.    {"distanceQuadraticAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_ZZZZ},
  101. };
  102.  
  103. static struct gl_builtin_uniform_element gl_FrontMaterial_elements[] = {
  104.    {"emission", {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW},
  105.    {"ambient", {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
  106.    {"diffuse", {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
  107.    {"specular", {STATE_MATERIAL, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
  108.    {"shininess", {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX},
  109. };
  110.  
  111. static struct gl_builtin_uniform_element gl_BackMaterial_elements[] = {
  112.    {"emission", {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW},
  113.    {"ambient", {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
  114.    {"diffuse", {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
  115.    {"specular", {STATE_MATERIAL, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
  116.    {"shininess", {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX},
  117. };
  118.  
  119. static struct gl_builtin_uniform_element gl_LightSource_elements[] = {
  120.    {"ambient", {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
  121.    {"diffuse", {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
  122.    {"specular", {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
  123.    {"position", {STATE_LIGHT, 0, STATE_POSITION}, SWIZZLE_XYZW},
  124.    {"halfVector", {STATE_LIGHT, 0, STATE_HALF_VECTOR}, SWIZZLE_XYZW},
  125.    {"spotDirection", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION},
  126.     MAKE_SWIZZLE4(SWIZZLE_X,
  127.                   SWIZZLE_Y,
  128.                   SWIZZLE_Z,
  129.                   SWIZZLE_Z)},
  130.    {"spotCosCutoff", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW},
  131.    {"spotCutoff", {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX},
  132.    {"spotExponent", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW},
  133.    {"constantAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX},
  134.    {"linearAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY},
  135.    {"quadraticAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ},
  136. };
  137.  
  138. static struct gl_builtin_uniform_element gl_LightModel_elements[] = {
  139.    {"ambient", {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW},
  140. };
  141.  
  142. static struct gl_builtin_uniform_element gl_FrontLightModelProduct_elements[] = {
  143.    {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW},
  144. };
  145.  
  146. static struct gl_builtin_uniform_element gl_BackLightModelProduct_elements[] = {
  147.    {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 1}, SWIZZLE_XYZW},
  148. };
  149.  
  150. static struct gl_builtin_uniform_element gl_FrontLightProduct_elements[] = {
  151.    {"ambient", {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
  152.    {"diffuse", {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
  153.    {"specular", {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
  154. };
  155.  
  156. static struct gl_builtin_uniform_element gl_BackLightProduct_elements[] = {
  157.    {"ambient", {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
  158.    {"diffuse", {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
  159.    {"specular", {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
  160. };
  161.  
  162. static struct gl_builtin_uniform_element gl_TextureEnvColor_elements[] = {
  163.    {NULL, {STATE_TEXENV_COLOR, 0}, SWIZZLE_XYZW},
  164. };
  165.  
  166. static struct gl_builtin_uniform_element gl_EyePlaneS_elements[] = {
  167.    {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_S}, SWIZZLE_XYZW},
  168. };
  169.  
  170. static struct gl_builtin_uniform_element gl_EyePlaneT_elements[] = {
  171.    {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_T}, SWIZZLE_XYZW},
  172. };
  173.  
  174. static struct gl_builtin_uniform_element gl_EyePlaneR_elements[] = {
  175.    {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_R}, SWIZZLE_XYZW},
  176. };
  177.  
  178. static struct gl_builtin_uniform_element gl_EyePlaneQ_elements[] = {
  179.    {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_Q}, SWIZZLE_XYZW},
  180. };
  181.  
  182. static struct gl_builtin_uniform_element gl_ObjectPlaneS_elements[] = {
  183.    {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_S}, SWIZZLE_XYZW},
  184. };
  185.  
  186. static struct gl_builtin_uniform_element gl_ObjectPlaneT_elements[] = {
  187.    {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_T}, SWIZZLE_XYZW},
  188. };
  189.  
  190. static struct gl_builtin_uniform_element gl_ObjectPlaneR_elements[] = {
  191.    {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_R}, SWIZZLE_XYZW},
  192. };
  193.  
  194. static struct gl_builtin_uniform_element gl_ObjectPlaneQ_elements[] = {
  195.    {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_Q}, SWIZZLE_XYZW},
  196. };
  197.  
  198. static struct gl_builtin_uniform_element gl_Fog_elements[] = {
  199.    {"color", {STATE_FOG_COLOR}, SWIZZLE_XYZW},
  200.    {"density", {STATE_FOG_PARAMS}, SWIZZLE_XXXX},
  201.    {"start", {STATE_FOG_PARAMS}, SWIZZLE_YYYY},
  202.    {"end", {STATE_FOG_PARAMS}, SWIZZLE_ZZZZ},
  203.    {"scale", {STATE_FOG_PARAMS}, SWIZZLE_WWWW},
  204. };
  205.  
  206. static struct gl_builtin_uniform_element gl_NormalScale_elements[] = {
  207.    {NULL, {STATE_NORMAL_SCALE}, SWIZZLE_XXXX},
  208. };
  209.  
  210. #define MATRIX(name, statevar, modifier)                                \
  211.    static struct gl_builtin_uniform_element name ## _elements[] = {     \
  212.       { NULL, { statevar, 0, 0, 0, modifier}, SWIZZLE_XYZW },           \
  213.       { NULL, { statevar, 0, 1, 1, modifier}, SWIZZLE_XYZW },           \
  214.       { NULL, { statevar, 0, 2, 2, modifier}, SWIZZLE_XYZW },           \
  215.       { NULL, { statevar, 0, 3, 3, modifier}, SWIZZLE_XYZW },           \
  216.    }
  217.  
  218. MATRIX(gl_ModelViewMatrix,
  219.        STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE);
  220. MATRIX(gl_ModelViewMatrixInverse,
  221.        STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS);
  222. MATRIX(gl_ModelViewMatrixTranspose,
  223.        STATE_MODELVIEW_MATRIX, 0);
  224. MATRIX(gl_ModelViewMatrixInverseTranspose,
  225.        STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE);
  226.  
  227. MATRIX(gl_ProjectionMatrix,
  228.        STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE);
  229. MATRIX(gl_ProjectionMatrixInverse,
  230.        STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS);
  231. MATRIX(gl_ProjectionMatrixTranspose,
  232.        STATE_PROJECTION_MATRIX, 0);
  233. MATRIX(gl_ProjectionMatrixInverseTranspose,
  234.        STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE);
  235.  
  236. MATRIX(gl_ModelViewProjectionMatrix,
  237.        STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE);
  238. MATRIX(gl_ModelViewProjectionMatrixInverse,
  239.        STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS);
  240. MATRIX(gl_ModelViewProjectionMatrixTranspose,
  241.        STATE_MVP_MATRIX, 0);
  242. MATRIX(gl_ModelViewProjectionMatrixInverseTranspose,
  243.        STATE_MVP_MATRIX, STATE_MATRIX_INVERSE);
  244.  
  245. MATRIX(gl_TextureMatrix,
  246.        STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE);
  247. MATRIX(gl_TextureMatrixInverse,
  248.        STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS);
  249. MATRIX(gl_TextureMatrixTranspose,
  250.        STATE_TEXTURE_MATRIX, 0);
  251. MATRIX(gl_TextureMatrixInverseTranspose,
  252.        STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE);
  253.  
  254. static struct gl_builtin_uniform_element gl_NormalMatrix_elements[] = {
  255.    { NULL, { STATE_MODELVIEW_MATRIX, 0, 0, 0, STATE_MATRIX_INVERSE},
  256.      SWIZZLE_XYZW },
  257.    { NULL, { STATE_MODELVIEW_MATRIX, 0, 1, 1, STATE_MATRIX_INVERSE},
  258.      SWIZZLE_XYZW },
  259.    { NULL, { STATE_MODELVIEW_MATRIX, 0, 2, 2, STATE_MATRIX_INVERSE},
  260.      SWIZZLE_XYZW },
  261. };
  262.  
  263. #undef MATRIX
  264.  
  265. #define STATEVAR(name) {#name, name ## _elements, Elements(name ## _elements)}
  266.  
  267. const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = {
  268.    STATEVAR(gl_DepthRange),
  269.    STATEVAR(gl_ClipPlane),
  270.    STATEVAR(gl_Point),
  271.    STATEVAR(gl_FrontMaterial),
  272.    STATEVAR(gl_BackMaterial),
  273.    STATEVAR(gl_LightSource),
  274.    STATEVAR(gl_LightModel),
  275.    STATEVAR(gl_FrontLightModelProduct),
  276.    STATEVAR(gl_BackLightModelProduct),
  277.    STATEVAR(gl_FrontLightProduct),
  278.    STATEVAR(gl_BackLightProduct),
  279.    STATEVAR(gl_TextureEnvColor),
  280.    STATEVAR(gl_EyePlaneS),
  281.    STATEVAR(gl_EyePlaneT),
  282.    STATEVAR(gl_EyePlaneR),
  283.    STATEVAR(gl_EyePlaneQ),
  284.    STATEVAR(gl_ObjectPlaneS),
  285.    STATEVAR(gl_ObjectPlaneT),
  286.    STATEVAR(gl_ObjectPlaneR),
  287.    STATEVAR(gl_ObjectPlaneQ),
  288.    STATEVAR(gl_Fog),
  289.  
  290.    STATEVAR(gl_ModelViewMatrix),
  291.    STATEVAR(gl_ModelViewMatrixInverse),
  292.    STATEVAR(gl_ModelViewMatrixTranspose),
  293.    STATEVAR(gl_ModelViewMatrixInverseTranspose),
  294.  
  295.    STATEVAR(gl_ProjectionMatrix),
  296.    STATEVAR(gl_ProjectionMatrixInverse),
  297.    STATEVAR(gl_ProjectionMatrixTranspose),
  298.    STATEVAR(gl_ProjectionMatrixInverseTranspose),
  299.  
  300.    STATEVAR(gl_ModelViewProjectionMatrix),
  301.    STATEVAR(gl_ModelViewProjectionMatrixInverse),
  302.    STATEVAR(gl_ModelViewProjectionMatrixTranspose),
  303.    STATEVAR(gl_ModelViewProjectionMatrixInverseTranspose),
  304.  
  305.    STATEVAR(gl_TextureMatrix),
  306.    STATEVAR(gl_TextureMatrixInverse),
  307.    STATEVAR(gl_TextureMatrixTranspose),
  308.    STATEVAR(gl_TextureMatrixInverseTranspose),
  309.  
  310.    STATEVAR(gl_NormalMatrix),
  311.    STATEVAR(gl_NormalScale),
  312.  
  313.    {NULL, NULL, 0}
  314. };
  315.  
  316. static GLboolean
  317. is_boolean_type(GLenum type)
  318. {
  319.    switch (type) {
  320.    case GL_BOOL:
  321.    case GL_BOOL_VEC2:
  322.    case GL_BOOL_VEC3:
  323.    case GL_BOOL_VEC4:
  324.       return GL_TRUE;
  325.    default:
  326.       return GL_FALSE;
  327.    }
  328. }
  329.  
  330.  
  331. static GLboolean
  332. is_sampler_type(GLenum type)
  333. {
  334.    switch (type) {
  335.    case GL_SAMPLER_1D:
  336.    case GL_SAMPLER_2D:
  337.    case GL_SAMPLER_3D:
  338.    case GL_SAMPLER_CUBE:
  339.    case GL_SAMPLER_1D_SHADOW:
  340.    case GL_SAMPLER_2D_SHADOW:
  341.    case GL_SAMPLER_2D_RECT_ARB:
  342.    case GL_SAMPLER_2D_RECT_SHADOW_ARB:
  343.    case GL_SAMPLER_1D_ARRAY_EXT:
  344.    case GL_SAMPLER_2D_ARRAY_EXT:
  345.    case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
  346.    case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
  347.       return GL_TRUE;
  348.    default:
  349.       return GL_FALSE;
  350.    }
  351. }
  352.  
  353.  
  354. static struct gl_program_parameter *
  355. get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
  356. {
  357.    const struct gl_program *prog = NULL;
  358.    GLint progPos;
  359.  
  360.    progPos = shProg->Uniforms->Uniforms[index].VertPos;
  361.    if (progPos >= 0) {
  362.       prog = &shProg->VertexProgram->Base;
  363.    }
  364.    else {
  365.       progPos = shProg->Uniforms->Uniforms[index].FragPos;
  366.       if (progPos >= 0) {
  367.          prog = &shProg->FragmentProgram->Base;
  368.       } else {
  369.          progPos = shProg->Uniforms->Uniforms[index].GeomPos;
  370.          if (progPos >= 0) {
  371.             prog = &shProg->GeometryProgram->Base;
  372.          }
  373.       }
  374.    }
  375.  
  376.    if (!prog || progPos < 0)
  377.       return NULL; /* should never happen */
  378.  
  379.    return &prog->Parameters->Parameters[progPos];
  380. }
  381.  
  382.  
  383. /**
  384.  * Called by glGetActiveUniform().
  385.  */
  386. static void
  387. _mesa_get_active_uniform(struct gl_context *ctx, GLuint program, GLuint index,
  388.                          GLsizei maxLength, GLsizei *length, GLint *size,
  389.                          GLenum *type, GLchar *nameOut)
  390. {
  391.    const struct gl_shader_program *shProg;
  392.    const struct gl_program *prog = NULL;
  393.    const struct gl_program_parameter *param;
  394.    GLint progPos;
  395.  
  396.    shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
  397.    if (!shProg)
  398.       return;
  399.  
  400.    if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
  401.       _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
  402.       return;
  403.    }
  404.  
  405.    progPos = shProg->Uniforms->Uniforms[index].VertPos;
  406.    if (progPos >= 0) {
  407.       prog = &shProg->VertexProgram->Base;
  408.    }
  409.    else {
  410.       progPos = shProg->Uniforms->Uniforms[index].FragPos;
  411.       if (progPos >= 0) {
  412.          prog = &shProg->FragmentProgram->Base;
  413.       } else {
  414.          progPos = shProg->Uniforms->Uniforms[index].GeomPos;
  415.          if (progPos >= 0) {
  416.             prog = &shProg->GeometryProgram->Base;
  417.          }
  418.       }
  419.    }
  420.  
  421.    if (!prog || progPos < 0)
  422.       return; /* should never happen */
  423.  
  424.    ASSERT(progPos < prog->Parameters->NumParameters);
  425.    param = &prog->Parameters->Parameters[progPos];
  426.  
  427.    if (nameOut) {
  428.       _mesa_copy_string(nameOut, maxLength, length, param->Name);
  429.    }
  430.  
  431.    if (size) {
  432.       GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
  433.       if ((GLint) param->Size > typeSize) {
  434.          /* This is an array.
  435.           * Array elements are placed on vector[4] boundaries so they're
  436.           * a multiple of four floats.  We round typeSize up to next multiple
  437.           * of four to get the right size below.
  438.           */
  439.          typeSize = (typeSize + 3) & ~3;
  440.       }
  441.       /* Note that the returned size is in units of the <type>, not bytes */
  442.       *size = param->Size / typeSize;
  443.    }
  444.  
  445.    if (type) {
  446.       *type = param->DataType;
  447.    }
  448. }
  449.  
  450.  
  451. static unsigned
  452. get_vector_elements(GLenum type)
  453. {
  454.    switch (type) {
  455.    case GL_FLOAT:
  456.    case GL_INT:
  457.    case GL_BOOL:
  458.    case GL_UNSIGNED_INT:
  459.    default: /* Catch all the various sampler types. */
  460.       return 1;
  461.  
  462.    case GL_FLOAT_VEC2:
  463.    case GL_INT_VEC2:
  464.    case GL_BOOL_VEC2:
  465.    case GL_UNSIGNED_INT_VEC2:
  466.       return 2;
  467.  
  468.    case GL_FLOAT_VEC3:
  469.    case GL_INT_VEC3:
  470.    case GL_BOOL_VEC3:
  471.    case GL_UNSIGNED_INT_VEC3:
  472.       return 3;
  473.  
  474.    case GL_FLOAT_VEC4:
  475.    case GL_INT_VEC4:
  476.    case GL_BOOL_VEC4:
  477.    case GL_UNSIGNED_INT_VEC4:
  478.       return 4;
  479.    }
  480. }
  481.  
  482. static void
  483. get_matrix_dims(GLenum type, GLint *rows, GLint *cols)
  484. {
  485.    switch (type) {
  486.    case GL_FLOAT_MAT2:
  487.       *rows = *cols = 2;
  488.       break;
  489.    case GL_FLOAT_MAT2x3:
  490.       *rows = 3;
  491.       *cols = 2;
  492.       break;
  493.    case GL_FLOAT_MAT2x4:
  494.       *rows = 4;
  495.       *cols = 2;
  496.       break;
  497.    case GL_FLOAT_MAT3:
  498.       *rows = 3;
  499.       *cols = 3;
  500.       break;
  501.    case GL_FLOAT_MAT3x2:
  502.       *rows = 2;
  503.       *cols = 3;
  504.       break;
  505.    case GL_FLOAT_MAT3x4:
  506.       *rows = 4;
  507.       *cols = 3;
  508.       break;
  509.    case GL_FLOAT_MAT4:
  510.       *rows = 4;
  511.       *cols = 4;
  512.       break;
  513.    case GL_FLOAT_MAT4x2:
  514.       *rows = 2;
  515.       *cols = 4;
  516.       break;
  517.    case GL_FLOAT_MAT4x3:
  518.       *rows = 3;
  519.       *cols = 4;
  520.       break;
  521.    default:
  522.       *rows = *cols = 0;
  523.    }
  524. }
  525.  
  526.  
  527. /**
  528.  * Determine the number of rows and columns occupied by a uniform
  529.  * according to its datatype.  For non-matrix types (such as GL_FLOAT_VEC4),
  530.  * the number of rows = 1 and cols = number of elements in the vector.
  531.  */
  532. static void
  533. get_uniform_rows_cols(const struct gl_program_parameter *p,
  534.                       GLint *rows, GLint *cols)
  535. {
  536.    get_matrix_dims(p->DataType, rows, cols);
  537.    if (*rows == 0 && *cols == 0) {
  538.       /* not a matrix type, probably a float or vector */
  539.       *rows = 1;
  540.       *cols = get_vector_elements(p->DataType);
  541.    }
  542. }
  543.  
  544.  
  545. /**
  546.  * Helper for get_uniform[fi]v() functions.
  547.  * Given a shader program name and uniform location, return a pointer
  548.  * to the shader program and return the program parameter position.
  549.  */
  550. static void
  551. lookup_uniform_parameter(struct gl_context *ctx, GLuint program, GLint location,
  552.                          struct gl_program **progOut, GLint *paramPosOut)
  553. {
  554.    struct gl_shader_program *shProg
  555.       = _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v");
  556.    struct gl_program *prog = NULL;
  557.    GLint progPos = -1;
  558.  
  559.    /* if shProg is NULL, we'll have already recorded an error */
  560.  
  561.    if (shProg) {
  562.       if (!shProg->Uniforms ||
  563.           location < 0 ||
  564.           location >= (GLint) shProg->Uniforms->NumUniforms) {
  565.          _mesa_error(ctx, GL_INVALID_OPERATION,  "glGetUniformfv(location)");
  566.       }
  567.       else {
  568.          /* OK, find the gl_program and program parameter location */
  569.          progPos = shProg->Uniforms->Uniforms[location].VertPos;
  570.          if (progPos >= 0) {
  571.             prog = &shProg->VertexProgram->Base;
  572.          }
  573.          else {
  574.             progPos = shProg->Uniforms->Uniforms[location].FragPos;
  575.             if (progPos >= 0) {
  576.                prog = &shProg->FragmentProgram->Base;
  577.             } else {
  578.                progPos = shProg->Uniforms->Uniforms[location].GeomPos;
  579.                if (progPos >= 0) {
  580.                   prog = &shProg->GeometryProgram->Base;
  581.                }
  582.             }
  583.          }
  584.       }
  585.    }
  586.  
  587.    *progOut = prog;
  588.    *paramPosOut = progPos;
  589. }
  590.  
  591.  
  592. /**
  593.  * GLGL uniform arrays and structs require special handling.
  594.  *
  595.  * The GL_ARB_shader_objects spec says that if you use
  596.  * glGetUniformLocation to get the location of an array, you CANNOT
  597.  * access other elements of the array by adding an offset to the
  598.  * returned location.  For example, you must call
  599.  * glGetUniformLocation("foo[16]") if you want to set the 16th element
  600.  * of the array with glUniform().
  601.  *
  602.  * HOWEVER, some other OpenGL drivers allow accessing array elements
  603.  * by adding an offset to the returned array location.  And some apps
  604.  * seem to depend on that behaviour.
  605.  *
  606.  * Mesa's gl_uniform_list doesn't directly support this since each
  607.  * entry in the list describes one uniform variable, not one uniform
  608.  * element.  We could insert dummy entries in the list for each array
  609.  * element after [0] but that causes complications elsewhere.
  610.  *
  611.  * We solve this problem by encoding two values in the location that's
  612.  * returned by glGetUniformLocation():
  613.  *  a) index into gl_uniform_list::Uniforms[] for the uniform
  614.  *  b) an array/field offset (0 for simple types)
  615.  *
  616.  * These two values are encoded in the high and low halves of a GLint.
  617.  * By putting the uniform number in the high part and the offset in the
  618.  * low part, we can support the unofficial ability to index into arrays
  619.  * by adding offsets to the location value.
  620.  */
  621. static void
  622. merge_location_offset(GLint *location, GLint offset)
  623. {
  624.    *location = (*location << 16) | offset;
  625. }
  626.  
  627.  
  628. /**
  629.  * Separate the uniform location and parameter offset.  See above.
  630.  */
  631. static void
  632. split_location_offset(GLint *location, GLint *offset)
  633. {
  634.    *offset = *location & 0xffff;
  635.    *location = *location >> 16;
  636. }
  637.  
  638.  
  639.  
  640. /**
  641.  * Called via glGetUniformfv().
  642.  */
  643. static void
  644. _mesa_get_uniformfv(struct gl_context *ctx, GLuint program, GLint location,
  645.                     GLfloat *params)
  646. {
  647.    struct gl_program *prog;
  648.    GLint paramPos;
  649.    GLint offset;
  650.  
  651.    split_location_offset(&location, &offset);
  652.  
  653.    lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
  654.  
  655.    if (prog) {
  656.       const struct gl_program_parameter *p =
  657.          &prog->Parameters->Parameters[paramPos];
  658.       GLint rows, cols, i, j, k;
  659.  
  660.       get_uniform_rows_cols(p, &rows, &cols);
  661.  
  662.       k = 0;
  663.       for (i = 0; i < rows; i++) {
  664.          const int base = paramPos + offset + i;
  665.  
  666.          for (j = 0; j < cols; j++ ) {
  667.             params[k++] = prog->Parameters->ParameterValues[base][j];
  668.          }
  669.       }
  670.    }
  671. }
  672.  
  673.  
  674. /**
  675.  * Called via glGetUniformiv().
  676.  * \sa _mesa_get_uniformfv, only difference is a cast.
  677.  */
  678. static void
  679. _mesa_get_uniformiv(struct gl_context *ctx, GLuint program, GLint location,
  680.                     GLint *params)
  681. {
  682.    struct gl_program *prog;
  683.    GLint paramPos;
  684.    GLint offset;
  685.  
  686.    split_location_offset(&location, &offset);
  687.  
  688.    lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
  689.  
  690.    if (prog) {
  691.       const struct gl_program_parameter *p =
  692.          &prog->Parameters->Parameters[paramPos];
  693.       GLint rows, cols, i, j, k;
  694.  
  695.       get_uniform_rows_cols(p, &rows, &cols);
  696.  
  697.       k = 0;
  698.       for (i = 0; i < rows; i++) {
  699.          const int base = paramPos + offset + i;
  700.  
  701.          for (j = 0; j < cols; j++ ) {
  702.             params[k++] = (GLint) prog->Parameters->ParameterValues[base][j];
  703.          }
  704.       }
  705.    }
  706. }
  707.  
  708.  
  709. /**
  710.  * Called via glGetUniformuiv().
  711.  * New in GL_EXT_gpu_shader4, OpenGL 3.0
  712.  * \sa _mesa_get_uniformfv, only difference is a cast.
  713.  */
  714. static void
  715. _mesa_get_uniformuiv(struct gl_context *ctx, GLuint program, GLint location,
  716.                      GLuint *params)
  717. {
  718.    struct gl_program *prog;
  719.    GLint paramPos;
  720.    GLint offset;
  721.  
  722.    split_location_offset(&location, &offset);
  723.  
  724.    lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
  725.  
  726.    if (prog) {
  727.       const struct gl_program_parameter *p =
  728.          &prog->Parameters->Parameters[paramPos];
  729.       GLint rows, cols, i, j, k;
  730.  
  731.       get_uniform_rows_cols(p, &rows, &cols);
  732.  
  733.       k = 0;
  734.       for (i = 0; i < rows; i++) {
  735.          const int base = paramPos + offset + i;
  736.  
  737.          for (j = 0; j < cols; j++ ) {
  738.             params[k++] = (GLuint) prog->Parameters->ParameterValues[base][j];
  739.          }
  740.       }
  741.    }
  742. }
  743.  
  744.  
  745. /**
  746.  * Called via glGetUniformLocation().
  747.  *
  748.  * The return value will encode two values, the uniform location and an
  749.  * offset (used for arrays, structs).
  750.  */
  751. GLint
  752. _mesa_get_uniform_location(struct gl_context *ctx, struct gl_shader_program *shProg,
  753.                            const GLchar *name)
  754. {
  755.    GLint offset = 0, location = -1;
  756.  
  757.    if (shProg->LinkStatus == GL_FALSE) {
  758.       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
  759.       return -1;
  760.    }
  761.  
  762.    /* XXX we should return -1 if the uniform was declared, but not
  763.     * actually used.
  764.     */
  765.  
  766.    /* XXX we need to be able to parse uniform names for structs and arrays
  767.     * such as:
  768.     *   mymatrix[1]
  769.     *   mystruct.field1
  770.     */
  771.  
  772.    {
  773.       /* handle 1-dimension arrays here... */
  774.       char *c = strchr(name, '[');
  775.       if (c) {
  776.          /* truncate name at [ */
  777.          const GLint len = c - name;
  778.          GLchar *newName = malloc(len + 1);
  779.          if (!newName)
  780.             return -1; /* out of mem */
  781.          memcpy(newName, name, len);
  782.          newName[len] = 0;
  783.  
  784.          location = _mesa_lookup_uniform(shProg->Uniforms, newName);
  785.          if (location >= 0) {
  786.             const GLint element = atoi(c + 1);
  787.             if (element > 0) {
  788.                /* get type of the uniform array element */
  789.                struct gl_program_parameter *p;
  790.                p = get_uniform_parameter(shProg, location);
  791.                if (p) {
  792.                   GLint rows, cols;
  793.                   get_matrix_dims(p->DataType, &rows, &cols);
  794.                   if (rows < 1)
  795.                      rows = 1;
  796.                   offset = element * rows;
  797.                }
  798.             }
  799.          }
  800.  
  801.          free(newName);
  802.       }
  803.    }
  804.  
  805.    if (location < 0) {
  806.       location = _mesa_lookup_uniform(shProg->Uniforms, name);
  807.    }
  808.  
  809.    if (location >= 0) {
  810.       merge_location_offset(&location, offset);
  811.    }
  812.  
  813.    return location;
  814. }
  815.  
  816.  
  817.  
  818. /**
  819.  * Update the vertex/fragment program's TexturesUsed array.
  820.  *
  821.  * This needs to be called after glUniform(set sampler var) is called.
  822.  * A call to glUniform(samplerVar, value) causes a sampler to point to a
  823.  * particular texture unit.  We know the sampler's texture target
  824.  * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
  825.  * set by glUniform() calls.
  826.  *
  827.  * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
  828.  * information to update the prog->TexturesUsed[] values.
  829.  * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
  830.  * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
  831.  * We'll use that info for state validation before rendering.
  832.  */
  833. void
  834. _mesa_update_shader_textures_used(struct gl_program *prog)
  835. {
  836.    GLuint s;
  837.  
  838.    memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
  839.  
  840.    for (s = 0; s < MAX_SAMPLERS; s++) {
  841.       if (prog->SamplersUsed & (1 << s)) {
  842.          GLuint unit = prog->SamplerUnits[s];
  843.          GLuint tgt = prog->SamplerTargets[s];
  844.          assert(unit < MAX_TEXTURE_IMAGE_UNITS);
  845.          assert(tgt < NUM_TEXTURE_TARGETS);
  846.          prog->TexturesUsed[unit] |= (1 << tgt);
  847.       }
  848.    }
  849. }
  850.  
  851.  
  852. /**
  853.  * Check if the type given by userType is allowed to set a uniform of the
  854.  * target type.  Generally, equivalence is required, but setting Boolean
  855.  * uniforms can be done with glUniformiv or glUniformfv.
  856.  */
  857. static GLboolean
  858. compatible_types(GLenum userType, GLenum targetType)
  859. {
  860.    if (userType == targetType)
  861.       return GL_TRUE;
  862.  
  863.    if (targetType == GL_BOOL && (userType == GL_FLOAT ||
  864.                                  userType == GL_UNSIGNED_INT ||
  865.                                  userType == GL_INT))
  866.       return GL_TRUE;
  867.  
  868.    if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
  869.                                       userType == GL_UNSIGNED_INT_VEC2 ||
  870.                                       userType == GL_INT_VEC2))
  871.       return GL_TRUE;
  872.  
  873.    if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
  874.                                       userType == GL_UNSIGNED_INT_VEC3 ||
  875.                                       userType == GL_INT_VEC3))
  876.       return GL_TRUE;
  877.  
  878.    if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
  879.                                       userType == GL_UNSIGNED_INT_VEC4 ||
  880.                                       userType == GL_INT_VEC4))
  881.       return GL_TRUE;
  882.  
  883.    if (is_sampler_type(targetType) && userType == GL_INT)
  884.       return GL_TRUE;
  885.  
  886.    return GL_FALSE;
  887. }
  888.  
  889.  
  890. /**
  891.  * Set the value of a program's uniform variable.
  892.  * \param program  the program whose uniform to update
  893.  * \param index  the index of the program parameter for the uniform
  894.  * \param offset  additional parameter slot offset (for arrays)
  895.  * \param type  the incoming datatype of 'values'
  896.  * \param count  the number of uniforms to set
  897.  * \param elems  number of elements per uniform (1, 2, 3 or 4)
  898.  * \param values  the new values, of datatype 'type'
  899.  */
  900. static void
  901. set_program_uniform(struct gl_context *ctx, struct gl_program *program,
  902.                     GLint index, GLint offset,
  903.                     GLenum type, GLsizei count, GLint elems,
  904.                     const void *values)
  905. {
  906.    const struct gl_program_parameter *param =
  907.       &program->Parameters->Parameters[index];
  908.  
  909.    assert(offset >= 0);
  910.    assert(elems >= 1);
  911.    assert(elems <= 4);
  912.  
  913.    if (!compatible_types(type, param->DataType)) {
  914.       _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
  915.       return;
  916.    }
  917.  
  918.    if (index + offset > (GLint) program->Parameters->Size) {
  919.       /* out of bounds! */
  920.       return;
  921.    }
  922.  
  923.    if (param->Type == PROGRAM_SAMPLER) {
  924.       /* This controls which texture unit which is used by a sampler */
  925.       GLboolean changed = GL_FALSE;
  926.       GLint i;
  927.  
  928.       /* this should have been caught by the compatible_types() check */
  929.       ASSERT(type == GL_INT);
  930.  
  931.       /* loop over number of samplers to change */
  932.       for (i = 0; i < count; i++) {
  933.          GLuint sampler =
  934.             (GLuint) program->Parameters->ParameterValues[index + offset + i][0];
  935.          GLuint texUnit = ((GLuint *) values)[i];
  936.  
  937.          /* check that the sampler (tex unit index) is legal */
  938.          if (texUnit >= ctx->Const.MaxTextureImageUnits) {
  939.             _mesa_error(ctx, GL_INVALID_VALUE,
  940.                         "glUniform1(invalid sampler/tex unit index for '%s')",
  941.                         param->Name);
  942.             return;
  943.          }
  944.  
  945.          /* This maps a sampler to a texture unit: */
  946.          if (sampler < MAX_SAMPLERS) {
  947. #if 0
  948.             printf("Set program %p sampler %d '%s' to unit %u\n",
  949.                    program, sampler, param->Name, texUnit);
  950. #endif
  951.             if (program->SamplerUnits[sampler] != texUnit) {
  952.                program->SamplerUnits[sampler] = texUnit;
  953.                changed = GL_TRUE;
  954.             }
  955.          }
  956.       }
  957.  
  958.       if (changed) {
  959.          /* When a sampler's value changes it usually requires rewriting
  960.           * a GPU program's TEX instructions since there may not be a
  961.           * sampler->texture lookup table.  We signal this with the
  962.           * ProgramStringNotify() callback.
  963.           */
  964.          FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
  965.          _mesa_update_shader_textures_used(program);
  966.          /* Do we need to care about the return value here?
  967.           * This should not be the first time the driver was notified of
  968.           * this program.
  969.           */
  970.          (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
  971.       }
  972.    }
  973.    else {
  974.       /* ordinary uniform variable */
  975.       const GLboolean isUniformBool = is_boolean_type(param->DataType);
  976.       const GLenum basicType = base_uniform_type(type);
  977.       const GLint slots = (param->Size + 3) / 4;
  978.       const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
  979.       GLsizei k, i;
  980.  
  981.       if ((GLint) param->Size > typeSize) {
  982.          /* an array */
  983.          /* we'll ignore extra data below */
  984.       }
  985.       else {
  986.          /* non-array: count must be at most one; count == 0 is handled by the loop below */
  987.          if (count > 1) {
  988.             _mesa_error(ctx, GL_INVALID_OPERATION,
  989.                         "glUniform(uniform '%s' is not an array)",
  990.                         param->Name);
  991.             return;
  992.          }
  993.       }
  994.  
  995.       /* loop over number of array elements */
  996.       for (k = 0; k < count; k++) {
  997.          GLfloat *uniformVal;
  998.  
  999.          if (offset + k >= slots) {
  1000.             /* Extra array data is ignored */
  1001.             break;
  1002.          }
  1003.  
  1004.          /* uniformVal (the destination) is always float[4] */
  1005.          uniformVal = program->Parameters->ParameterValues[index + offset + k];
  1006.  
  1007.          if (basicType == GL_INT) {
  1008.             /* convert user's ints to floats */
  1009.             const GLint *iValues = ((const GLint *) values) + k * elems;
  1010.             for (i = 0; i < elems; i++) {
  1011.                uniformVal[i] = (GLfloat) iValues[i];
  1012.             }
  1013.          }
  1014.          else if (basicType == GL_UNSIGNED_INT) {
  1015.             /* convert user's uints to floats */
  1016.             const GLuint *iValues = ((const GLuint *) values) + k * elems;
  1017.             for (i = 0; i < elems; i++) {
  1018.                uniformVal[i] = (GLfloat) iValues[i];
  1019.             }
  1020.          }
  1021.          else {
  1022.             const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
  1023.             assert(basicType == GL_FLOAT);
  1024.             for (i = 0; i < elems; i++) {
  1025.                uniformVal[i] = fValues[i];
  1026.             }
  1027.          }
  1028.  
  1029.          /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
  1030.          if (isUniformBool) {
  1031.             for (i = 0; i < elems; i++) {
  1032.                uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
  1033.             }
  1034.          }
  1035.       }
  1036.    }
  1037. }
  1038.  
  1039.  
  1040. /**
  1041.  * Called via glUniform*() functions.
  1042.  */
  1043. void
  1044. _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
  1045.               GLint location, GLsizei count,
  1046.               const GLvoid *values, GLenum type)
  1047. {
  1048.    struct gl_uniform *uniform;
  1049.    GLint elems, offset;
  1050.  
  1051.    if (!shProg || !shProg->LinkStatus) {
  1052.       _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
  1053.       return;
  1054.    }
  1055.  
  1056.    if (location == -1)
  1057.       return;   /* The standard specifies this as a no-op */
  1058.  
  1059.    if (location < -1) {
  1060.       _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location=%d)",
  1061.                   location);
  1062.       return;
  1063.    }
  1064.  
  1065.    split_location_offset(&location, &offset);
  1066.  
  1067.    if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
  1068.       _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location=%d)", location);
  1069.       return;
  1070.    }
  1071.  
  1072.    if (count < 0) {
  1073.       _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
  1074.       return;
  1075.    }
  1076.  
  1077.    elems = _mesa_sizeof_glsl_type(type);
  1078.  
  1079.    FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
  1080.  
  1081.    uniform = &shProg->Uniforms->Uniforms[location];
  1082.  
  1083.    if (ctx->Shader.Flags & GLSL_UNIFORMS) {
  1084.       const GLenum basicType = base_uniform_type(type);
  1085.       GLint i;
  1086.       printf("Mesa: set program %u uniform %s (loc %d) to: ",
  1087.              shProg->Name, uniform->Name, location);
  1088.       if (basicType == GL_INT) {
  1089.          const GLint *v = (const GLint *) values;
  1090.          for (i = 0; i < count * elems; i++) {
  1091.             printf("%d ", v[i]);
  1092.          }
  1093.       }
  1094.       else if (basicType == GL_UNSIGNED_INT) {
  1095.          const GLuint *v = (const GLuint *) values;
  1096.          for (i = 0; i < count * elems; i++) {
  1097.             printf("%u ", v[i]);
  1098.          }
  1099.       }
  1100.       else {
  1101.          const GLfloat *v = (const GLfloat *) values;
  1102.          assert(basicType == GL_FLOAT);
  1103.          for (i = 0; i < count * elems; i++) {
  1104.             printf("%g ", v[i]);
  1105.          }
  1106.       }
  1107.       printf("\n");
  1108.    }
  1109.  
  1110.    /* A uniform var may be used by both a vertex shader and a fragment
  1111.     * shader.  We may need to update one or both shader's uniform here:
  1112.     */
  1113.    if (shProg->VertexProgram) {
  1114.       /* convert uniform location to program parameter index */
  1115.       GLint index = uniform->VertPos;
  1116.       if (index >= 0) {
  1117.          set_program_uniform(ctx, &shProg->VertexProgram->Base,
  1118.                              index, offset, type, count, elems, values);
  1119.       }
  1120.    }
  1121.  
  1122.    if (shProg->FragmentProgram) {
  1123.       /* convert uniform location to program parameter index */
  1124.       GLint index = uniform->FragPos;
  1125.       if (index >= 0) {
  1126.          set_program_uniform(ctx, &shProg->FragmentProgram->Base,
  1127.                              index, offset, type, count, elems, values);
  1128.       }
  1129.    }
  1130.  
  1131.    if (shProg->GeometryProgram) {
  1132.       /* convert uniform location to program parameter index */
  1133.       GLint index = uniform->GeomPos;
  1134.       if (index >= 0) {
  1135.          set_program_uniform(ctx, &shProg->GeometryProgram->Base,
  1136.                              index, offset, type, count, elems, values);
  1137.       }
  1138.    }
  1139.  
  1140.    uniform->Initialized = GL_TRUE;
  1141. }
  1142.  
  1143.  
  1144. /**
  1145.  * Set a matrix-valued program parameter.
  1146.  */
  1147. static void
  1148. set_program_uniform_matrix(struct gl_context *ctx, struct gl_program *program,
  1149.                            GLuint index, GLuint offset,
  1150.                            GLuint count, GLuint rows, GLuint cols,
  1151.                            GLboolean transpose, const GLfloat *values)
  1152. {
  1153.    GLuint mat, row, col;
  1154.    GLuint src = 0;
  1155.    const struct gl_program_parameter * param = &program->Parameters->Parameters[index];
  1156.    const GLuint slots = (param->Size + 3) / 4;
  1157.    const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
  1158.    GLint nr, nc;
  1159.  
  1160.    /* check that the number of rows, columns is correct */
  1161.    get_matrix_dims(param->DataType, &nr, &nc);
  1162.    if (rows != nr || cols != nc) {
  1163.       _mesa_error(ctx, GL_INVALID_OPERATION,
  1164.                   "glUniformMatrix(matrix size mismatch)");
  1165.       return;
  1166.    }
  1167.  
  1168.    if ((GLint) param->Size <= typeSize) {
  1169.       /* non-array: count must be at most one; count == 0 is handled by the loop below */
  1170.       if (count > 1) {
  1171.          _mesa_error(ctx, GL_INVALID_OPERATION,
  1172.                      "glUniformMatrix(uniform is not an array)");
  1173.          return;
  1174.       }
  1175.    }
  1176.  
  1177.    /*
  1178.     * Note: the _columns_ of a matrix are stored in program registers, not
  1179.     * the rows.  So, the loops below look a little funny.
  1180.     * XXX could optimize this a bit...
  1181.     */
  1182.  
  1183.    /* loop over matrices */
  1184.    for (mat = 0; mat < count; mat++) {
  1185.  
  1186.       /* each matrix: */
  1187.       for (col = 0; col < cols; col++) {
  1188.          GLfloat *v;
  1189.          if (offset >= slots) {
  1190.             /* Ignore writes beyond the end of (the used part of) an array */
  1191.             return;
  1192.          }
  1193.          v = program->Parameters->ParameterValues[index + offset];
  1194.          for (row = 0; row < rows; row++) {
  1195.             if (transpose) {
  1196.                v[row] = values[src + row * cols + col];
  1197.             }
  1198.             else {
  1199.                v[row] = values[src + col * rows + row];
  1200.             }
  1201.          }
  1202.  
  1203.          offset++;
  1204.       }
  1205.  
  1206.       src += rows * cols;  /* next matrix */
  1207.    }
  1208. }
  1209.  
  1210.  
  1211. /**
  1212.  * Called by glUniformMatrix*() functions.
  1213.  * Note: cols=2, rows=4  ==>  array[2] of vec4
  1214.  */
  1215. void
  1216. _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
  1217.                      GLint cols, GLint rows,
  1218.                      GLint location, GLsizei count,
  1219.                      GLboolean transpose, const GLfloat *values)
  1220. {
  1221.    struct gl_uniform *uniform;
  1222.    GLint offset;
  1223.  
  1224.    if (!shProg || !shProg->LinkStatus) {
  1225.       _mesa_error(ctx, GL_INVALID_OPERATION,
  1226.          "glUniformMatrix(program not linked)");
  1227.       return;
  1228.    }
  1229.  
  1230.    if (location == -1)
  1231.       return;   /* The standard specifies this as a no-op */
  1232.  
  1233.    if (location < -1) {
  1234.       _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)");
  1235.       return;
  1236.    }
  1237.  
  1238.    split_location_offset(&location, &offset);
  1239.  
  1240.    if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
  1241.       _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
  1242.       return;
  1243.    }
  1244.    if (values == NULL) {
  1245.       _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
  1246.       return;
  1247.    }
  1248.  
  1249.    FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
  1250.  
  1251.    uniform = &shProg->Uniforms->Uniforms[location];
  1252.  
  1253.    if (shProg->VertexProgram) {
  1254.       /* convert uniform location to program parameter index */
  1255.       GLint index = uniform->VertPos;
  1256.       if (index >= 0) {
  1257.          set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
  1258.                                     index, offset,
  1259.                                     count, rows, cols, transpose, values);
  1260.       }
  1261.    }
  1262.  
  1263.    if (shProg->FragmentProgram) {
  1264.       /* convert uniform location to program parameter index */
  1265.       GLint index = uniform->FragPos;
  1266.       if (index >= 0) {
  1267.          set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
  1268.                                     index, offset,
  1269.                                     count, rows, cols, transpose, values);
  1270.       }
  1271.    }
  1272.  
  1273.    if (shProg->GeometryProgram) {
  1274.       /* convert uniform location to program parameter index */
  1275.       GLint index = uniform->GeomPos;
  1276.       if (index >= 0) {
  1277.          set_program_uniform_matrix(ctx, &shProg->GeometryProgram->Base,
  1278.                                     index, offset,
  1279.                                     count, rows, cols, transpose, values);
  1280.       }
  1281.    }
  1282.  
  1283.    uniform->Initialized = GL_TRUE;
  1284. }
  1285.  
  1286.  
  1287. void GLAPIENTRY
  1288. _mesa_Uniform1fARB(GLint location, GLfloat v0)
  1289. {
  1290.    GET_CURRENT_CONTEXT(ctx);
  1291.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_FLOAT);
  1292. }
  1293.  
  1294. void GLAPIENTRY
  1295. _mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
  1296. {
  1297.    GET_CURRENT_CONTEXT(ctx);
  1298.    GLfloat v[2];
  1299.    v[0] = v0;
  1300.    v[1] = v1;
  1301.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC2);
  1302. }
  1303.  
  1304. void GLAPIENTRY
  1305. _mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
  1306. {
  1307.    GET_CURRENT_CONTEXT(ctx);
  1308.    GLfloat v[3];
  1309.    v[0] = v0;
  1310.    v[1] = v1;
  1311.    v[2] = v2;
  1312.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC3);
  1313. }
  1314.  
  1315. void GLAPIENTRY
  1316. _mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
  1317.                    GLfloat v3)
  1318. {
  1319.    GET_CURRENT_CONTEXT(ctx);
  1320.    GLfloat v[4];
  1321.    v[0] = v0;
  1322.    v[1] = v1;
  1323.    v[2] = v2;
  1324.    v[3] = v3;
  1325.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC4);
  1326. }
  1327.  
  1328. void GLAPIENTRY
  1329. _mesa_Uniform1iARB(GLint location, GLint v0)
  1330. {
  1331.    GET_CURRENT_CONTEXT(ctx);
  1332.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_INT);
  1333. }
  1334.  
  1335. void GLAPIENTRY
  1336. _mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
  1337. {
  1338.    GET_CURRENT_CONTEXT(ctx);
  1339.    GLint v[2];
  1340.    v[0] = v0;
  1341.    v[1] = v1;
  1342.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC2);
  1343. }
  1344.  
  1345. void GLAPIENTRY
  1346. _mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
  1347. {
  1348.    GET_CURRENT_CONTEXT(ctx);
  1349.    GLint v[3];
  1350.    v[0] = v0;
  1351.    v[1] = v1;
  1352.    v[2] = v2;
  1353.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC3);
  1354. }
  1355.  
  1356. void GLAPIENTRY
  1357. _mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
  1358. {
  1359.    GET_CURRENT_CONTEXT(ctx);
  1360.    GLint v[4];
  1361.    v[0] = v0;
  1362.    v[1] = v1;
  1363.    v[2] = v2;
  1364.    v[3] = v3;
  1365.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC4);
  1366. }
  1367.  
  1368. void GLAPIENTRY
  1369. _mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
  1370. {
  1371.    GET_CURRENT_CONTEXT(ctx);
  1372.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT);
  1373. }
  1374.  
  1375. void GLAPIENTRY
  1376. _mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
  1377. {
  1378.    GET_CURRENT_CONTEXT(ctx);
  1379.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC2);
  1380. }
  1381.  
  1382. void GLAPIENTRY
  1383. _mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
  1384. {
  1385.    GET_CURRENT_CONTEXT(ctx);
  1386.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC3);
  1387. }
  1388.  
  1389. void GLAPIENTRY
  1390. _mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
  1391. {
  1392.    GET_CURRENT_CONTEXT(ctx);
  1393.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC4);
  1394. }
  1395.  
  1396. void GLAPIENTRY
  1397. _mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
  1398. {
  1399.    GET_CURRENT_CONTEXT(ctx);
  1400.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT);
  1401. }
  1402.  
  1403. void GLAPIENTRY
  1404. _mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
  1405. {
  1406.    GET_CURRENT_CONTEXT(ctx);
  1407.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC2);
  1408. }
  1409.  
  1410. void GLAPIENTRY
  1411. _mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
  1412. {
  1413.    GET_CURRENT_CONTEXT(ctx);
  1414.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC3);
  1415. }
  1416.  
  1417. void GLAPIENTRY
  1418. _mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
  1419. {
  1420.    GET_CURRENT_CONTEXT(ctx);
  1421.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC4);
  1422. }
  1423.  
  1424.  
  1425. /** OpenGL 3.0 GLuint-valued functions **/
  1426. void GLAPIENTRY
  1427. _mesa_Uniform1ui(GLint location, GLuint v0)
  1428. {
  1429.    GET_CURRENT_CONTEXT(ctx);
  1430.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_UNSIGNED_INT);
  1431. }
  1432.  
  1433. void GLAPIENTRY
  1434. _mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
  1435. {
  1436.    GET_CURRENT_CONTEXT(ctx);
  1437.    GLuint v[2];
  1438.    v[0] = v0;
  1439.    v[1] = v1;
  1440.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC2);
  1441. }
  1442.  
  1443. void GLAPIENTRY
  1444. _mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
  1445. {
  1446.    GET_CURRENT_CONTEXT(ctx);
  1447.    GLuint v[3];
  1448.    v[0] = v0;
  1449.    v[1] = v1;
  1450.    v[2] = v2;
  1451.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC3);
  1452. }
  1453.  
  1454. void GLAPIENTRY
  1455. _mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
  1456. {
  1457.    GET_CURRENT_CONTEXT(ctx);
  1458.    GLuint v[4];
  1459.    v[0] = v0;
  1460.    v[1] = v1;
  1461.    v[2] = v2;
  1462.    v[3] = v3;
  1463.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC4);
  1464. }
  1465.  
  1466. void GLAPIENTRY
  1467. _mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
  1468. {
  1469.    GET_CURRENT_CONTEXT(ctx);
  1470.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT);
  1471. }
  1472.  
  1473. void GLAPIENTRY
  1474. _mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
  1475. {
  1476.    GET_CURRENT_CONTEXT(ctx);
  1477.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC2);
  1478. }
  1479.  
  1480. void GLAPIENTRY
  1481. _mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
  1482. {
  1483.    GET_CURRENT_CONTEXT(ctx);
  1484.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC3);
  1485. }
  1486.  
  1487. void GLAPIENTRY
  1488. _mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
  1489. {
  1490.    GET_CURRENT_CONTEXT(ctx);
  1491.    _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC4);
  1492. }
  1493.  
  1494.  
  1495.  
  1496. void GLAPIENTRY
  1497. _mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
  1498.                           const GLfloat * value)
  1499. {
  1500.    GET_CURRENT_CONTEXT(ctx);
  1501.    _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
  1502.                         2, 2, location, count, transpose, value);
  1503. }
  1504.  
  1505. void GLAPIENTRY
  1506. _mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
  1507.                           const GLfloat * value)
  1508. {
  1509.    GET_CURRENT_CONTEXT(ctx);
  1510.    _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
  1511.                         3, 3, location, count, transpose, value);
  1512. }
  1513.  
  1514. void GLAPIENTRY
  1515. _mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
  1516.                           const GLfloat * value)
  1517. {
  1518.    GET_CURRENT_CONTEXT(ctx);
  1519.    _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
  1520.                         4, 4, location, count, transpose, value);
  1521. }
  1522.  
  1523.  
  1524. /**
  1525.  * Non-square UniformMatrix are OpenGL 2.1
  1526.  */
  1527. void GLAPIENTRY
  1528. _mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
  1529.                          const GLfloat *value)
  1530. {
  1531.    GET_CURRENT_CONTEXT(ctx);
  1532.    _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
  1533.                         2, 3, location, count, transpose, value);
  1534. }
  1535.  
  1536. void GLAPIENTRY
  1537. _mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
  1538.                          const GLfloat *value)
  1539. {
  1540.    GET_CURRENT_CONTEXT(ctx);
  1541.    _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
  1542.                         3, 2, location, count, transpose, value);
  1543. }
  1544.  
  1545. void GLAPIENTRY
  1546. _mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
  1547.                          const GLfloat *value)
  1548. {
  1549.    GET_CURRENT_CONTEXT(ctx);
  1550.    _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
  1551.                         2, 4, location, count, transpose, value);
  1552. }
  1553.  
  1554. void GLAPIENTRY
  1555. _mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
  1556.                          const GLfloat *value)
  1557. {
  1558.    GET_CURRENT_CONTEXT(ctx);
  1559.    _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
  1560.                         4, 2, location, count, transpose, value);
  1561. }
  1562.  
  1563. void GLAPIENTRY
  1564. _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
  1565.                          const GLfloat *value)
  1566. {
  1567.    GET_CURRENT_CONTEXT(ctx);
  1568.    _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
  1569.                         3, 4, location, count, transpose, value);
  1570. }
  1571.  
  1572. void GLAPIENTRY
  1573. _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
  1574.                          const GLfloat *value)
  1575. {
  1576.    GET_CURRENT_CONTEXT(ctx);
  1577.    _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
  1578.                         4, 3, location, count, transpose, value);
  1579. }
  1580.  
  1581.  
  1582. void GLAPIENTRY
  1583. _mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat *params)
  1584. {
  1585.    GET_CURRENT_CONTEXT(ctx);
  1586.    _mesa_get_uniformfv(ctx, program, location, params);
  1587. }
  1588.  
  1589.  
  1590. void GLAPIENTRY
  1591. _mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint *params)
  1592. {
  1593.    GET_CURRENT_CONTEXT(ctx);
  1594.    _mesa_get_uniformiv(ctx, program, location, params);
  1595. }
  1596.  
  1597.  
  1598. /* GL3 */
  1599. void GLAPIENTRY
  1600. _mesa_GetUniformuiv(GLhandleARB program, GLint location, GLuint *params)
  1601. {
  1602.    GET_CURRENT_CONTEXT(ctx);
  1603.    _mesa_get_uniformuiv(ctx, program, location, params);
  1604. }
  1605.  
  1606.  
  1607.  
  1608. GLint GLAPIENTRY
  1609. _mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
  1610. {
  1611.    struct gl_shader_program *shProg;
  1612.  
  1613.    GET_CURRENT_CONTEXT(ctx);
  1614.  
  1615.    shProg = _mesa_lookup_shader_program_err(ctx, programObj,
  1616.                                             "glGetUniformLocation");
  1617.    if (!shProg)
  1618.       return -1;
  1619.  
  1620.    return _mesa_get_uniform_location(ctx, shProg, name);
  1621. }
  1622.  
  1623.  
  1624. void GLAPIENTRY
  1625. _mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
  1626.                           GLsizei maxLength, GLsizei * length, GLint * size,
  1627.                           GLenum * type, GLcharARB * name)
  1628. {
  1629.    GET_CURRENT_CONTEXT(ctx);
  1630.    _mesa_get_active_uniform(ctx, program, index, maxLength, length, size,
  1631.                             type, name);
  1632. }
  1633.  
  1634.  
  1635. /**
  1636.  * Plug in shader uniform-related functions into API dispatch table.
  1637.  */
  1638. void
  1639. _mesa_init_shader_uniform_dispatch(struct _glapi_table *exec)
  1640. {
  1641. #if FEATURE_GL
  1642.    SET_Uniform1fARB(exec, _mesa_Uniform1fARB);
  1643.    SET_Uniform2fARB(exec, _mesa_Uniform2fARB);
  1644.    SET_Uniform3fARB(exec, _mesa_Uniform3fARB);
  1645.    SET_Uniform4fARB(exec, _mesa_Uniform4fARB);
  1646.    SET_Uniform1iARB(exec, _mesa_Uniform1iARB);
  1647.    SET_Uniform2iARB(exec, _mesa_Uniform2iARB);
  1648.    SET_Uniform3iARB(exec, _mesa_Uniform3iARB);
  1649.    SET_Uniform4iARB(exec, _mesa_Uniform4iARB);
  1650.    SET_Uniform1fvARB(exec, _mesa_Uniform1fvARB);
  1651.    SET_Uniform2fvARB(exec, _mesa_Uniform2fvARB);
  1652.    SET_Uniform3fvARB(exec, _mesa_Uniform3fvARB);
  1653.    SET_Uniform4fvARB(exec, _mesa_Uniform4fvARB);
  1654.    SET_Uniform1ivARB(exec, _mesa_Uniform1ivARB);
  1655.    SET_Uniform2ivARB(exec, _mesa_Uniform2ivARB);
  1656.    SET_Uniform3ivARB(exec, _mesa_Uniform3ivARB);
  1657.    SET_Uniform4ivARB(exec, _mesa_Uniform4ivARB);
  1658.    SET_UniformMatrix2fvARB(exec, _mesa_UniformMatrix2fvARB);
  1659.    SET_UniformMatrix3fvARB(exec, _mesa_UniformMatrix3fvARB);
  1660.    SET_UniformMatrix4fvARB(exec, _mesa_UniformMatrix4fvARB);
  1661.  
  1662.    SET_GetActiveUniformARB(exec, _mesa_GetActiveUniformARB);
  1663.    SET_GetUniformLocationARB(exec, _mesa_GetUniformLocationARB);
  1664.    SET_GetUniformfvARB(exec, _mesa_GetUniformfvARB);
  1665.    SET_GetUniformivARB(exec, _mesa_GetUniformivARB);
  1666.  
  1667.    /* OpenGL 2.1 */
  1668.    SET_UniformMatrix2x3fv(exec, _mesa_UniformMatrix2x3fv);
  1669.    SET_UniformMatrix3x2fv(exec, _mesa_UniformMatrix3x2fv);
  1670.    SET_UniformMatrix2x4fv(exec, _mesa_UniformMatrix2x4fv);
  1671.    SET_UniformMatrix4x2fv(exec, _mesa_UniformMatrix4x2fv);
  1672.    SET_UniformMatrix3x4fv(exec, _mesa_UniformMatrix3x4fv);
  1673.    SET_UniformMatrix4x3fv(exec, _mesa_UniformMatrix4x3fv);
  1674.  
  1675.    /* OpenGL 3.0 */
  1676.    /* XXX finish dispatch */
  1677.    SET_Uniform1uiEXT(exec, _mesa_Uniform1ui);
  1678.    SET_Uniform2uiEXT(exec, _mesa_Uniform2ui);
  1679.    SET_Uniform3uiEXT(exec, _mesa_Uniform3ui);
  1680.    SET_Uniform4uiEXT(exec, _mesa_Uniform4ui);
  1681.    SET_Uniform1uivEXT(exec, _mesa_Uniform1uiv);
  1682.    SET_Uniform2uivEXT(exec, _mesa_Uniform2uiv);
  1683.    SET_Uniform3uivEXT(exec, _mesa_Uniform3uiv);
  1684.    SET_Uniform4uivEXT(exec, _mesa_Uniform4uiv);
  1685.    SET_GetUniformuivEXT(exec, _mesa_GetUniformuiv);
  1686.  
  1687.  
  1688. #endif /* FEATURE_GL */
  1689. }
  1690.