Home | History | Annotate | Download | only in main
      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, 2011 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 #include <stdlib.h>
     27 
     28 #include "main/core.h"
     29 #include "main/context.h"
     30 #include "ir.h"
     31 #include "ir_uniform.h"
     32 #include "program/hash_table.h"
     33 #include "../glsl/program.h"
     34 #include "../glsl/ir_uniform.h"
     35 #include "main/shaderapi.h"
     36 #include "main/shaderobj.h"
     37 #include "uniforms.h"
     38 
     39 
     40 extern "C" void GLAPIENTRY
     41 _mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
     42                           GLsizei maxLength, GLsizei *length, GLint *size,
     43                           GLenum *type, GLcharARB *nameOut)
     44 {
     45    GET_CURRENT_CONTEXT(ctx);
     46    struct gl_shader_program *shProg =
     47       _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
     48 
     49    ASSERT_OUTSIDE_BEGIN_END(ctx);
     50 
     51    if (!shProg)
     52       return;
     53 
     54    if (index >= shProg->NumUserUniformStorage) {
     55       _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
     56       return;
     57    }
     58 
     59    const struct gl_uniform_storage *const uni = &shProg->UniformStorage[index];
     60 
     61    if (nameOut) {
     62       _mesa_copy_string(nameOut, maxLength, length, uni->name);
     63    }
     64 
     65    if (size) {
     66       /* array_elements is zero for non-arrays, but the API requires that 1 be
     67        * returned.
     68        */
     69       *size = MAX2(1, uni->array_elements);
     70    }
     71 
     72    if (type) {
     73       *type = uni->type->gl_type;
     74    }
     75 }
     76 
     77 extern "C" void GLAPIENTRY
     78 _mesa_GetActiveUniformsiv(GLuint program,
     79 			  GLsizei uniformCount,
     80 			  const GLuint *uniformIndices,
     81 			  GLenum pname,
     82 			  GLint *params)
     83 {
     84    GET_CURRENT_CONTEXT(ctx);
     85    struct gl_shader_program *shProg;
     86    GLsizei i;
     87 
     88    shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
     89    if (!shProg)
     90       return;
     91 
     92    if (uniformCount < 0) {
     93       _mesa_error(ctx, GL_INVALID_VALUE,
     94 		  "glGetUniformIndices(uniformCount < 0)");
     95       return;
     96    }
     97 
     98    for (i = 0; i < uniformCount; i++) {
     99       GLuint index = uniformIndices[i];
    100 
    101       if (index >= shProg->NumUserUniformStorage) {
    102 	 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)");
    103 	 return;
    104       }
    105    }
    106 
    107    for (i = 0; i < uniformCount; i++) {
    108       GLuint index = uniformIndices[i];
    109       const struct gl_uniform_storage *uni = &shProg->UniformStorage[index];
    110 
    111       switch (pname) {
    112       case GL_UNIFORM_TYPE:
    113 	 params[i] = uni->type->gl_type;
    114 	 break;
    115 
    116       case GL_UNIFORM_SIZE:
    117 	 /* array_elements is zero for non-arrays, but the API requires that 1 be
    118 	  * returned.
    119 	  */
    120 	 params[i] = MAX2(1, uni->array_elements);
    121 	 break;
    122 
    123       case GL_UNIFORM_NAME_LENGTH:
    124 	 params[i] = strlen(uni->name) + 1;
    125 	 break;
    126 
    127       case GL_UNIFORM_BLOCK_INDEX:
    128 	 params[i] = uni->block_index;
    129 	 break;
    130 
    131       case GL_UNIFORM_OFFSET:
    132 	 params[i] = uni->offset;
    133 	 break;
    134 
    135       case GL_UNIFORM_ARRAY_STRIDE:
    136 	 params[i] = uni->array_stride;
    137 	 break;
    138 
    139       case GL_UNIFORM_MATRIX_STRIDE:
    140 	 params[i] = uni->matrix_stride;
    141 	 break;
    142 
    143       case GL_UNIFORM_IS_ROW_MAJOR:
    144 	 params[i] = uni->row_major;
    145 	 break;
    146 
    147       default:
    148 	 _mesa_error(ctx, GL_INVALID_ENUM, "glGetActiveUniformsiv(pname)");
    149 	 return;
    150       }
    151    }
    152 }
    153 
    154 static bool
    155 validate_uniform_parameters(struct gl_context *ctx,
    156 			    struct gl_shader_program *shProg,
    157 			    GLint location, GLsizei count,
    158 			    unsigned *loc,
    159 			    unsigned *array_index,
    160 			    const char *caller,
    161 			    bool negative_one_is_not_valid)
    162 {
    163    if (!shProg || !shProg->LinkStatus) {
    164       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", caller);
    165       return false;
    166    }
    167 
    168    if (location == -1) {
    169       /* For glGetUniform, page 264 (page 278 of the PDF) of the OpenGL 2.1
    170        * spec says:
    171        *
    172        *     "The error INVALID_OPERATION is generated if program has not been
    173        *     linked successfully, or if location is not a valid location for
    174        *     program."
    175        *
    176        * For glUniform, page 82 (page 96 of the PDF) of the OpenGL 2.1 spec
    177        * says:
    178        *
    179        *     "If the value of location is -1, the Uniform* commands will
    180        *     silently ignore the data passed in, and the current uniform
    181        *     values will not be changed."
    182        *
    183        * Allowing -1 for the location parameter of glUniform allows
    184        * applications to avoid error paths in the case that, for example, some
    185        * uniform variable is removed by the compiler / linker after
    186        * optimization.  In this case, the new value of the uniform is dropped
    187        * on the floor.  For the case of glGetUniform, there is nothing
    188        * sensible to do for a location of -1.
    189        *
    190        * The negative_one_is_not_valid flag selects between the two behaviors.
    191        */
    192       if (negative_one_is_not_valid) {
    193 	 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
    194 		     caller, location);
    195       }
    196 
    197       return false;
    198    }
    199 
    200    /* From page 12 (page 26 of the PDF) of the OpenGL 2.1 spec:
    201     *
    202     *     "If a negative number is provided where an argument of type sizei or
    203     *     sizeiptr is specified, the error INVALID_VALUE is generated."
    204     */
    205    if (count < 0) {
    206       _mesa_error(ctx, GL_INVALID_VALUE, "%s(count < 0)", caller);
    207       return false;
    208    }
    209 
    210    /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
    211     *
    212     *     "If any of the following conditions occur, an INVALID_OPERATION
    213     *     error is generated by the Uniform* commands, and no uniform values
    214     *     are changed:
    215     *
    216     *     ...
    217     *
    218     *         - if no variable with a location of location exists in the
    219     *           program object currently in use and location is not -1,
    220     *         - if count is greater than one, and the uniform declared in the
    221     *           shader is not an array variable,
    222     */
    223    if (location < -1) {
    224       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
    225                   caller, location);
    226       return false;
    227    }
    228 
    229    _mesa_uniform_split_location_offset(location, loc, array_index);
    230 
    231    if (*loc >= shProg->NumUserUniformStorage) {
    232       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
    233 		  caller, location);
    234       return false;
    235    }
    236 
    237    if (shProg->UniformStorage[*loc].array_elements == 0 && count > 1) {
    238       _mesa_error(ctx, GL_INVALID_OPERATION,
    239 		  "%s(count > 1 for non-array, location=%d)",
    240 		  caller, location);
    241       return false;
    242    }
    243 
    244    /* If the uniform is an array, check that array_index is in bounds.
    245     * If not an array, check that array_index is zero.
    246     * array_index is unsigned so no need to check for less than zero.
    247     */
    248    unsigned limit = shProg->UniformStorage[*loc].array_elements;
    249    if (limit == 0)
    250       limit = 1;
    251    if (*array_index >= limit) {
    252       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
    253 		  caller, location);
    254       return false;
    255    }
    256    return true;
    257 }
    258 
    259 /**
    260  * Called via glGetUniform[fiui]v() to get the current value of a uniform.
    261  */
    262 extern "C" void
    263 _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
    264 		  GLsizei bufSize, enum glsl_base_type returnType,
    265 		  GLvoid *paramsOut)
    266 {
    267    struct gl_shader_program *shProg =
    268       _mesa_lookup_shader_program_err(ctx, program, "glGetUniformfv");
    269    struct gl_uniform_storage *uni;
    270    unsigned loc, offset;
    271 
    272    if (!validate_uniform_parameters(ctx, shProg, location, 1,
    273 				    &loc, &offset, "glGetUniform", true))
    274       return;
    275 
    276    uni = &shProg->UniformStorage[loc];
    277 
    278    {
    279       unsigned elements = (uni->type->is_sampler())
    280 	 ? 1 : uni->type->components();
    281 
    282       /* Calculate the source base address *BEFORE* modifying elements to
    283        * account for the size of the user's buffer.
    284        */
    285       const union gl_constant_value *const src =
    286 	 &uni->storage[offset * elements];
    287 
    288       assert(returnType == GLSL_TYPE_FLOAT || returnType == GLSL_TYPE_INT ||
    289              returnType == GLSL_TYPE_UINT);
    290       /* The three (currently) supported types all have the same size,
    291        * which is of course the same as their union. That'll change
    292        * with glGetUniformdv()...
    293        */
    294       unsigned bytes = sizeof(src[0]) * elements;
    295       if (bufSize < 0 || bytes > (unsigned) bufSize) {
    296 	 _mesa_error( ctx, GL_INVALID_OPERATION,
    297 	             "glGetnUniform*vARB(out of bounds: bufSize is %d,"
    298 	             " but %u bytes are required)", bufSize, bytes );
    299 	 return;
    300       }
    301 
    302       /* If the return type and the uniform's native type are "compatible,"
    303        * just memcpy the data.  If the types are not compatible, perform a
    304        * slower convert-and-copy process.
    305        */
    306       if (returnType == uni->type->base_type
    307 	  || ((returnType == GLSL_TYPE_INT
    308 	       || returnType == GLSL_TYPE_UINT
    309 	       || returnType == GLSL_TYPE_SAMPLER)
    310 	      &&
    311 	      (uni->type->base_type == GLSL_TYPE_INT
    312 	       || uni->type->base_type == GLSL_TYPE_UINT
    313 	       || uni->type->base_type == GLSL_TYPE_SAMPLER))) {
    314 	 memcpy(paramsOut, src, bytes);
    315       } else {
    316 	 union gl_constant_value *const dst =
    317 	    (union gl_constant_value *) paramsOut;
    318 
    319 	 /* This code could be optimized by putting the loop inside the switch
    320 	  * statements.  However, this is not expected to be
    321 	  * performance-critical code.
    322 	  */
    323 	 for (unsigned i = 0; i < elements; i++) {
    324 	    switch (returnType) {
    325 	    case GLSL_TYPE_FLOAT:
    326 	       switch (uni->type->base_type) {
    327 	       case GLSL_TYPE_UINT:
    328 		  dst[i].f = (float) src[i].u;
    329 		  break;
    330 	       case GLSL_TYPE_INT:
    331 	       case GLSL_TYPE_SAMPLER:
    332 		  dst[i].f = (float) src[i].i;
    333 		  break;
    334 	       case GLSL_TYPE_BOOL:
    335 		  dst[i].f = src[i].i ? 1.0f : 0.0f;
    336 		  break;
    337 	       default:
    338 		  assert(!"Should not get here.");
    339 		  break;
    340 	       }
    341 	       break;
    342 
    343 	    case GLSL_TYPE_INT:
    344 	    case GLSL_TYPE_UINT:
    345 	       switch (uni->type->base_type) {
    346 	       case GLSL_TYPE_FLOAT:
    347 		  /* While the GL 3.2 core spec doesn't explicitly
    348 		   * state how conversion of float uniforms to integer
    349 		   * values works, in section 6.2 "State Tables" on
    350 		   * page 267 it says:
    351 		   *
    352 		   *     "Unless otherwise specified, when floating
    353 		   *      point state is returned as integer values or
    354 		   *      integer state is returned as floating-point
    355 		   *      values it is converted in the fashion
    356 		   *      described in section 6.1.2"
    357 		   *
    358 		   * That section, on page 248, says:
    359 		   *
    360 		   *     "If GetIntegerv or GetInteger64v are called,
    361 		   *      a floating-point value is rounded to the
    362 		   *      nearest integer..."
    363 		   */
    364 		  dst[i].i = IROUND(src[i].f);
    365 		  break;
    366 	       case GLSL_TYPE_BOOL:
    367 		  dst[i].i = src[i].i ? 1 : 0;
    368 		  break;
    369 	       default:
    370 		  assert(!"Should not get here.");
    371 		  break;
    372 	       }
    373 	       break;
    374 
    375 	    default:
    376 	       assert(!"Should not get here.");
    377 	       break;
    378 	    }
    379 	 }
    380       }
    381    }
    382 }
    383 
    384 static void
    385 log_uniform(const void *values, enum glsl_base_type basicType,
    386 	    unsigned rows, unsigned cols, unsigned count,
    387 	    bool transpose,
    388 	    const struct gl_shader_program *shProg,
    389 	    GLint location,
    390 	    const struct gl_uniform_storage *uni)
    391 {
    392 
    393    const union gl_constant_value *v = (const union gl_constant_value *) values;
    394    const unsigned elems = rows * cols * count;
    395    const char *const extra = (cols == 1) ? "uniform" : "uniform matrix";
    396 
    397    printf("Mesa: set program %u %s \"%s\" (loc %d, type \"%s\", "
    398 	  "transpose = %s) to: ",
    399 	  shProg->Name, extra, uni->name, location, uni->type->name,
    400 	  transpose ? "true" : "false");
    401    for (unsigned i = 0; i < elems; i++) {
    402       if (i != 0 && ((i % rows) == 0))
    403 	 printf(", ");
    404 
    405       switch (basicType) {
    406       case GLSL_TYPE_UINT:
    407 	 printf("%u ", v[i].u);
    408 	 break;
    409       case GLSL_TYPE_INT:
    410 	 printf("%d ", v[i].i);
    411 	 break;
    412       case GLSL_TYPE_FLOAT:
    413 	 printf("%g ", v[i].f);
    414 	 break;
    415       default:
    416 	 assert(!"Should not get here.");
    417 	 break;
    418       }
    419    }
    420    printf("\n");
    421    fflush(stdout);
    422 }
    423 
    424 #if 0
    425 static void
    426 log_program_parameters(const struct gl_shader_program *shProg)
    427 {
    428    static const char *stages[] = {
    429       "vertex", "fragment", "geometry"
    430    };
    431 
    432    assert(Elements(stages) == MESA_SHADER_TYPES);
    433 
    434    for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
    435       if (shProg->_LinkedShaders[i] == NULL)
    436 	 continue;
    437 
    438       const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program;
    439 
    440       printf("Program %d %s shader parameters:\n",
    441 	     shProg->Name, stages[i]);
    442       for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) {
    443 	 printf("%s: %p %f %f %f %f\n",
    444 		prog->Parameters->Parameters[j].Name,
    445 		prog->Parameters->ParameterValues[j],
    446 		prog->Parameters->ParameterValues[j][0].f,
    447 		prog->Parameters->ParameterValues[j][1].f,
    448 		prog->Parameters->ParameterValues[j][2].f,
    449 		prog->Parameters->ParameterValues[j][3].f);
    450       }
    451    }
    452    fflush(stdout);
    453 }
    454 #endif
    455 
    456 /**
    457  * Propagate some values from uniform backing storage to driver storage
    458  *
    459  * Values propagated from uniform backing storage to driver storage
    460  * have all format / type conversions previously requested by the
    461  * driver applied.  This function is most often called by the
    462  * implementations of \c glUniform1f, etc. and \c glUniformMatrix2f,
    463  * etc.
    464  *
    465  * \param uni          Uniform whose data is to be propagated to driver storage
    466  * \param array_index  If \c uni is an array, this is the element of
    467  *                     the array to be propagated.
    468  * \param count        Number of array elements to propagate.
    469  */
    470 extern "C" void
    471 _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni,
    472 					   unsigned array_index,
    473 					   unsigned count)
    474 {
    475    unsigned i;
    476 
    477    /* vector_elements and matrix_columns can be 0 for samplers.
    478     */
    479    const unsigned components = MAX2(1, uni->type->vector_elements);
    480    const unsigned vectors = MAX2(1, uni->type->matrix_columns);
    481 
    482    /* Store the data in the driver's requested type in the driver's storage
    483     * areas.
    484     */
    485    unsigned src_vector_byte_stride = components * 4;
    486 
    487    for (i = 0; i < uni->num_driver_storage; i++) {
    488       struct gl_uniform_driver_storage *const store = &uni->driver_storage[i];
    489       uint8_t *dst = (uint8_t *) store->data;
    490       const unsigned extra_stride =
    491 	 store->element_stride - (vectors * store->vector_stride);
    492       const uint8_t *src =
    493 	 (uint8_t *) (&uni->storage[array_index * (components * vectors)].i);
    494 
    495 #if 0
    496       printf("%s: %p[%d] components=%u vectors=%u count=%u vector_stride=%u "
    497 	     "extra_stride=%u\n",
    498 	     __func__, dst, array_index, components,
    499 	     vectors, count, store->vector_stride, extra_stride);
    500 #endif
    501 
    502       dst += array_index * store->element_stride;
    503 
    504       switch (store->format) {
    505       case uniform_native:
    506       case uniform_bool_int_0_1: {
    507 	 unsigned j;
    508 	 unsigned v;
    509 
    510 	 for (j = 0; j < count; j++) {
    511 	    for (v = 0; v < vectors; v++) {
    512 	       memcpy(dst, src, src_vector_byte_stride);
    513 	       src += src_vector_byte_stride;
    514 	       dst += store->vector_stride;
    515 	    }
    516 
    517 	    dst += extra_stride;
    518 	 }
    519 	 break;
    520       }
    521 
    522       case uniform_int_float:
    523       case uniform_bool_float: {
    524 	 const int *isrc = (const int *) src;
    525 	 unsigned j;
    526 	 unsigned v;
    527 	 unsigned c;
    528 
    529 	 for (j = 0; j < count; j++) {
    530 	    for (v = 0; v < vectors; v++) {
    531 	       for (c = 0; c < components; c++) {
    532 		  ((float *) dst)[c] = (float) *isrc;
    533 		  isrc++;
    534 	       }
    535 
    536 	       dst += store->vector_stride;
    537 	    }
    538 
    539 	    dst += extra_stride;
    540 	 }
    541 	 break;
    542       }
    543 
    544       case uniform_bool_int_0_not0: {
    545 	 const int *isrc = (const int *) src;
    546 	 unsigned j;
    547 	 unsigned v;
    548 	 unsigned c;
    549 
    550 	 for (j = 0; j < count; j++) {
    551 	    for (v = 0; v < vectors; v++) {
    552 	       for (c = 0; c < components; c++) {
    553 		  ((int *) dst)[c] = *isrc == 0 ? 0 : ~0;
    554 		  isrc++;
    555 	       }
    556 
    557 	       dst += store->vector_stride;
    558 	    }
    559 
    560 	    dst += extra_stride;
    561 	 }
    562 	 break;
    563       }
    564 
    565       default:
    566 	 assert(!"Should not get here.");
    567 	 break;
    568       }
    569    }
    570 }
    571 
    572 /**
    573  * Called via glUniform*() functions.
    574  */
    575 extern "C" void
    576 _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
    577 	      GLint location, GLsizei count,
    578               const GLvoid *values, GLenum type)
    579 {
    580    unsigned loc, offset;
    581    unsigned components;
    582    unsigned src_components;
    583    enum glsl_base_type basicType;
    584    struct gl_uniform_storage *uni;
    585 
    586    ASSERT_OUTSIDE_BEGIN_END(ctx);
    587 
    588    if (!validate_uniform_parameters(ctx, shProg, location, count,
    589 				    &loc, &offset, "glUniform", false))
    590       return;
    591 
    592    uni = &shProg->UniformStorage[loc];
    593 
    594    /* Verify that the types are compatible.
    595     */
    596    switch (type) {
    597    case GL_FLOAT:
    598       basicType = GLSL_TYPE_FLOAT;
    599       src_components = 1;
    600       break;
    601    case GL_FLOAT_VEC2:
    602       basicType = GLSL_TYPE_FLOAT;
    603       src_components = 2;
    604       break;
    605    case GL_FLOAT_VEC3:
    606       basicType = GLSL_TYPE_FLOAT;
    607       src_components = 3;
    608       break;
    609    case GL_FLOAT_VEC4:
    610       basicType = GLSL_TYPE_FLOAT;
    611       src_components = 4;
    612       break;
    613    case GL_UNSIGNED_INT:
    614       basicType = GLSL_TYPE_UINT;
    615       src_components = 1;
    616       break;
    617    case GL_UNSIGNED_INT_VEC2:
    618       basicType = GLSL_TYPE_UINT;
    619       src_components = 2;
    620       break;
    621    case GL_UNSIGNED_INT_VEC3:
    622       basicType = GLSL_TYPE_UINT;
    623       src_components = 3;
    624       break;
    625    case GL_UNSIGNED_INT_VEC4:
    626       basicType = GLSL_TYPE_UINT;
    627       src_components = 4;
    628       break;
    629    case GL_INT:
    630       basicType = GLSL_TYPE_INT;
    631       src_components = 1;
    632       break;
    633    case GL_INT_VEC2:
    634       basicType = GLSL_TYPE_INT;
    635       src_components = 2;
    636       break;
    637    case GL_INT_VEC3:
    638       basicType = GLSL_TYPE_INT;
    639       src_components = 3;
    640       break;
    641    case GL_INT_VEC4:
    642       basicType = GLSL_TYPE_INT;
    643       src_components = 4;
    644       break;
    645    case GL_BOOL:
    646    case GL_BOOL_VEC2:
    647    case GL_BOOL_VEC3:
    648    case GL_BOOL_VEC4:
    649    case GL_FLOAT_MAT2:
    650    case GL_FLOAT_MAT2x3:
    651    case GL_FLOAT_MAT2x4:
    652    case GL_FLOAT_MAT3x2:
    653    case GL_FLOAT_MAT3:
    654    case GL_FLOAT_MAT3x4:
    655    case GL_FLOAT_MAT4x2:
    656    case GL_FLOAT_MAT4x3:
    657    case GL_FLOAT_MAT4:
    658    default:
    659       _mesa_problem(NULL, "Invalid type in %s", __func__);
    660       return;
    661    }
    662 
    663    if (uni->type->is_sampler()) {
    664       components = 1;
    665    } else {
    666       components = uni->type->vector_elements;
    667    }
    668 
    669    bool match;
    670    switch (uni->type->base_type) {
    671    case GLSL_TYPE_BOOL:
    672       match = true;
    673       break;
    674    case GLSL_TYPE_SAMPLER:
    675       match = (basicType == GLSL_TYPE_INT);
    676       break;
    677    default:
    678       match = (basicType == uni->type->base_type);
    679       break;
    680    }
    681 
    682    if (uni->type->is_matrix() || components != src_components || !match) {
    683       _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
    684       return;
    685    }
    686 
    687    if (ctx->Shader.Flags & GLSL_UNIFORMS) {
    688       log_uniform(values, basicType, components, 1, count,
    689 		  false, shProg, location, uni);
    690    }
    691 
    692    /* Page 100 (page 116 of the PDF) of the OpenGL 3.0 spec says:
    693     *
    694     *     "Setting a sampler's value to i selects texture image unit number
    695     *     i. The values of i range from zero to the implementation- dependent
    696     *     maximum supported number of texture image units."
    697     *
    698     * In addition, table 2.3, "Summary of GL errors," on page 17 (page 33 of
    699     * the PDF) says:
    700     *
    701     *     "Error         Description                    Offending command
    702     *                                                   ignored?
    703     *     ...
    704     *     INVALID_VALUE  Numeric argument out of range  Yes"
    705     *
    706     * Based on that, when an invalid sampler is specified, we generate a
    707     * GL_INVALID_VALUE error and ignore the command.
    708     */
    709    if (uni->type->is_sampler()) {
    710       int i;
    711 
    712       for (i = 0; i < count; i++) {
    713 	 const unsigned texUnit = ((unsigned *) values)[i];
    714 
    715          /* check that the sampler (tex unit index) is legal */
    716          if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
    717             _mesa_error(ctx, GL_INVALID_VALUE,
    718                         "glUniform1i(invalid sampler/tex unit index for "
    719 			"uniform %d)",
    720                         location);
    721             return;
    722          }
    723       }
    724    }
    725 
    726    /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
    727     *
    728     *     "When loading N elements starting at an arbitrary position k in a
    729     *     uniform declared as an array, elements k through k + N - 1 in the
    730     *     array will be replaced with the new values. Values for any array
    731     *     element that exceeds the highest array element index used, as
    732     *     reported by GetActiveUniform, will be ignored by the GL."
    733     *
    734     * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
    735     * will have already generated an error.
    736     */
    737    if (uni->array_elements != 0) {
    738       count = MIN2(count, (int) (uni->array_elements - offset));
    739    }
    740 
    741    FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
    742 
    743    /* Store the data in the "actual type" backing storage for the uniform.
    744     */
    745    if (!uni->type->is_boolean()) {
    746       memcpy(&uni->storage[components * offset], values,
    747 	     sizeof(uni->storage[0]) * components * count);
    748    } else {
    749       const union gl_constant_value *src =
    750 	 (const union gl_constant_value *) values;
    751       union gl_constant_value *dst = &uni->storage[components * offset];
    752       const unsigned elems = components * count;
    753       unsigned i;
    754 
    755       for (i = 0; i < elems; i++) {
    756 	 if (basicType == GLSL_TYPE_FLOAT) {
    757 	    dst[i].i = src[i].f != 0.0f ? 1 : 0;
    758 	 } else {
    759 	    dst[i].i = src[i].i != 0    ? 1 : 0;
    760 	 }
    761       }
    762    }
    763 
    764    uni->initialized = true;
    765 
    766    _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
    767 
    768    /* If the uniform is a sampler, do the extra magic necessary to propagate
    769     * the changes through.
    770     */
    771    if (uni->type->is_sampler()) {
    772       int i;
    773 
    774       for (i = 0; i < count; i++) {
    775 	 shProg->SamplerUnits[uni->sampler + offset + i] =
    776 	    ((unsigned *) values)[i];
    777       }
    778 
    779       bool flushed = false;
    780       for (i = 0; i < MESA_SHADER_TYPES; i++) {
    781 	 struct gl_shader *const sh = shProg->_LinkedShaders[i];
    782 
    783 	 /* If the shader stage doesn't use any samplers, don't bother
    784 	  * checking if any samplers have changed.
    785 	  */
    786 	 if (sh == NULL || sh->active_samplers == 0)
    787 	    continue;
    788 
    789 	 struct gl_program *const prog = sh->Program;
    790 
    791 	 assert(sizeof(prog->SamplerUnits) == sizeof(shProg->SamplerUnits));
    792 
    793 	 /* Determine if any of the samplers used by this shader stage have
    794 	  * been modified.
    795 	  */
    796 	 bool changed = false;
    797 	 for (unsigned j = 0; j < Elements(prog->SamplerUnits); j++) {
    798 	    if ((sh->active_samplers & (1U << j)) != 0
    799 		&& (prog->SamplerUnits[j] != shProg->SamplerUnits[j])) {
    800 	       changed = true;
    801 	       break;
    802 	    }
    803 	 }
    804 
    805 	 if (changed) {
    806 	    if (!flushed) {
    807 	       FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
    808 	       flushed = true;
    809 	    }
    810 
    811 	    memcpy(prog->SamplerUnits,
    812 		   shProg->SamplerUnits,
    813 		   sizeof(shProg->SamplerUnits));
    814 
    815 	    _mesa_update_shader_textures_used(shProg, prog);
    816             if (ctx->Driver.SamplerUniformChange)
    817 	       ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog);
    818 	 }
    819       }
    820    }
    821 }
    822 
    823 /**
    824  * Called by glUniformMatrix*() functions.
    825  * Note: cols=2, rows=4  ==>  array[2] of vec4
    826  */
    827 extern "C" void
    828 _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
    829 		     GLuint cols, GLuint rows,
    830                      GLint location, GLsizei count,
    831                      GLboolean transpose, const GLfloat *values)
    832 {
    833    unsigned loc, offset;
    834    unsigned vectors;
    835    unsigned components;
    836    unsigned elements;
    837    struct gl_uniform_storage *uni;
    838 
    839    ASSERT_OUTSIDE_BEGIN_END(ctx);
    840 
    841    if (!validate_uniform_parameters(ctx, shProg, location, count,
    842 				    &loc, &offset, "glUniformMatrix", false))
    843       return;
    844 
    845    uni = &shProg->UniformStorage[loc];
    846    if (!uni->type->is_matrix()) {
    847       _mesa_error(ctx, GL_INVALID_OPERATION,
    848 		  "glUniformMatrix(non-matrix uniform)");
    849       return;
    850    }
    851 
    852    assert(!uni->type->is_sampler());
    853    vectors = uni->type->matrix_columns;
    854    components = uni->type->vector_elements;
    855 
    856    /* Verify that the types are compatible.  This is greatly simplified for
    857     * matrices because they can only have a float base type.
    858     */
    859    if (vectors != cols || components != rows) {
    860       _mesa_error(ctx, GL_INVALID_OPERATION,
    861 		  "glUniformMatrix(matrix size mismatch)");
    862       return;
    863    }
    864 
    865    /* GL_INVALID_VALUE is generated if `transpose' is not GL_FALSE.
    866     * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml */
    867    if (ctx->API == API_OPENGLES || ctx->API == API_OPENGLES2) {
    868       if (transpose) {
    869 	 _mesa_error(ctx, GL_INVALID_VALUE,
    870 		     "glUniformMatrix(matrix transpose is not GL_FALSE)");
    871 	 return;
    872       }
    873    }
    874 
    875    if (ctx->Shader.Flags & GLSL_UNIFORMS) {
    876       log_uniform(values, GLSL_TYPE_FLOAT, components, vectors, count,
    877 		  bool(transpose), shProg, location, uni);
    878    }
    879 
    880    /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
    881     *
    882     *     "When loading N elements starting at an arbitrary position k in a
    883     *     uniform declared as an array, elements k through k + N - 1 in the
    884     *     array will be replaced with the new values. Values for any array
    885     *     element that exceeds the highest array element index used, as
    886     *     reported by GetActiveUniform, will be ignored by the GL."
    887     *
    888     * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
    889     * will have already generated an error.
    890     */
    891    if (uni->array_elements != 0) {
    892       count = MIN2(count, (int) (uni->array_elements - offset));
    893    }
    894 
    895    FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
    896 
    897    /* Store the data in the "actual type" backing storage for the uniform.
    898     */
    899    elements = components * vectors;
    900 
    901    if (!transpose) {
    902       memcpy(&uni->storage[elements * offset], values,
    903 	     sizeof(uni->storage[0]) * elements * count);
    904    } else {
    905       /* Copy and transpose the matrix.
    906        */
    907       const float *src = values;
    908       float *dst = &uni->storage[elements * offset].f;
    909 
    910       for (int i = 0; i < count; i++) {
    911 	 for (unsigned r = 0; r < rows; r++) {
    912 	    for (unsigned c = 0; c < cols; c++) {
    913 	       dst[(c * components) + r] = src[c + (r * vectors)];
    914 	    }
    915 	 }
    916 
    917 	 dst += elements;
    918 	 src += elements;
    919       }
    920    }
    921 
    922    uni->initialized = true;
    923 
    924    _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
    925 }
    926 
    927 /**
    928  * Called via glGetUniformLocation().
    929  *
    930  * Returns the uniform index into UniformStorage (also the
    931  * glGetActiveUniformsiv uniform index), and stores the referenced
    932  * array offset in *offset, or GL_INVALID_INDEX (-1).  Those two
    933  * return values can be encoded into a uniform location for
    934  * glUniform* using _mesa_uniform_merge_location_offset(index, offset).
    935  */
    936 extern "C" unsigned
    937 _mesa_get_uniform_location(struct gl_context *ctx,
    938                            struct gl_shader_program *shProg,
    939                            const GLchar *name,
    940                            unsigned *out_offset)
    941 {
    942    const size_t len = strlen(name);
    943    long offset;
    944    bool array_lookup;
    945    char *name_copy;
    946 
    947    /* If the name ends with a ']', assume that it refers to some element of an
    948     * array.  Malformed array references will fail the hash table look up
    949     * below, so it doesn't matter that they are not caught here.  This code
    950     * only wants to catch the "leaf" array references so that arrays of
    951     * structures containing arrays will be handled correctly.
    952     */
    953    if (name[len-1] == ']') {
    954       unsigned i;
    955 
    956       /* Walk backwards over the string looking for a non-digit character.
    957        * This had better be the opening bracket for an array index.
    958        *
    959        * Initially, i specifies the location of the ']'.  Since the string may
    960        * contain only the ']' charcater, walk backwards very carefully.
    961        */
    962       for (i = len - 1; (i > 0) && isdigit(name[i-1]); --i)
    963 	 /* empty */ ;
    964 
    965       /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says:
    966        *
    967        *     "The first element of a uniform array is identified using the
    968        *     name of the uniform array appended with "[0]". Except if the last
    969        *     part of the string name indicates a uniform array, then the
    970        *     location of the first element of that array can be retrieved by
    971        *     either using the name of the uniform array, or the name of the
    972        *     uniform array appended with "[0]"."
    973        *
    974        * Page 79 (page 93 of the PDF) of the OpenGL 2.1 spec says:
    975        *
    976        *     "name must be a null terminated string, without white space."
    977        *
    978        * Return an error if there is no opening '[' to match the closing ']'.
    979        * An error will also be returned if there is intervening white space
    980        * (or other non-digit characters) before the opening '['.
    981        */
    982       if ((i == 0) || name[i-1] != '[')
    983 	 return GL_INVALID_INDEX;
    984 
    985       /* Return an error if there are no digits between the opening '[' to
    986        * match the closing ']'.
    987        */
    988       if (i == (len - 1))
    989 	 return GL_INVALID_INDEX;
    990 
    991       /* Make a new string that is a copy of the old string up to (but not
    992        * including) the '[' character.
    993        */
    994       name_copy = (char *) malloc(i);
    995       memcpy(name_copy, name, i - 1);
    996       name_copy[i-1] = '\0';
    997 
    998       offset = strtol(&name[i], NULL, 10);
    999       if (offset < 0) {
   1000 	 free(name_copy);
   1001 	 return GL_INVALID_INDEX;
   1002       }
   1003 
   1004       array_lookup = true;
   1005    } else {
   1006       name_copy = (char *) name;
   1007       offset = 0;
   1008       array_lookup = false;
   1009    }
   1010 
   1011    unsigned location = 0;
   1012    const bool found = shProg->UniformHash->get(location, name_copy);
   1013 
   1014    assert(!found
   1015 	  || strcmp(name_copy, shProg->UniformStorage[location].name) == 0);
   1016 
   1017    /* Free the temporary buffer *before* possibly returning an error.
   1018     */
   1019    if (name_copy != name)
   1020       free(name_copy);
   1021 
   1022    if (!found)
   1023       return GL_INVALID_INDEX;
   1024 
   1025    /* If the uniform is an array, fail if the index is out of bounds.
   1026     * (A negative index is caught above.)  This also fails if the uniform
   1027     * is not an array, but the user is trying to index it, because
   1028     * array_elements is zero and offset >= 0.
   1029     */
   1030    if (array_lookup
   1031 	 && offset >= shProg->UniformStorage[location].array_elements) {
   1032       return GL_INVALID_INDEX;
   1033    }
   1034 
   1035    *out_offset = offset;
   1036    return location;
   1037 }
   1038 
   1039 extern "C" bool
   1040 _mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
   1041 				 char *errMsg, size_t errMsgLength)
   1042 {
   1043    const glsl_type *unit_types[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
   1044 
   1045    memset(unit_types, 0, sizeof(unit_types));
   1046 
   1047    for (unsigned i = 0; i < shProg->NumUserUniformStorage; i++) {
   1048       const struct gl_uniform_storage *const storage =
   1049 	 &shProg->UniformStorage[i];
   1050       const glsl_type *const t = (storage->type->is_array())
   1051 	 ? storage->type->fields.array : storage->type;
   1052 
   1053       if (!t->is_sampler())
   1054 	 continue;
   1055 
   1056       const unsigned count = MAX2(1, storage->type->array_size());
   1057       for (unsigned j = 0; j < count; j++) {
   1058 	 const unsigned unit = storage->storage[j].i;
   1059 
   1060 	 /* The types of the samplers associated with a particular texture
   1061 	  * unit must be an exact match.  Page 74 (page 89 of the PDF) of the
   1062 	  * OpenGL 3.3 core spec says:
   1063 	  *
   1064 	  *     "It is not allowed to have variables of different sampler
   1065 	  *     types pointing to the same texture image unit within a program
   1066 	  *     object."
   1067 	  */
   1068 	 if (unit_types[unit] == NULL) {
   1069 	    unit_types[unit] = t;
   1070 	 } else if (unit_types[unit] != t) {
   1071 	    _mesa_snprintf(errMsg, errMsgLength,
   1072 			   "Texture unit %d is accessed both as %s and %s",
   1073 			   unit, unit_types[unit]->name, t->name);
   1074 	    return false;
   1075 	 }
   1076       }
   1077    }
   1078 
   1079    return true;
   1080 }
   1081