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  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     22  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     23  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     24  * OTHER DEALINGS IN THE SOFTWARE.
     25  */
     26 
     27 #include <stdlib.h>
     28 
     29 #include "main/core.h"
     30 #include "main/context.h"
     31 #include "main/shaderapi.h"
     32 #include "main/shaderobj.h"
     33 #include "main/uniforms.h"
     34 #include "compiler/glsl/ir.h"
     35 #include "compiler/glsl/ir_uniform.h"
     36 #include "compiler/glsl/glsl_parser_extras.h"
     37 #include "compiler/glsl/program.h"
     38 #include "util/bitscan.h"
     39 
     40 
     41 extern "C" void GLAPIENTRY
     42 _mesa_GetActiveUniform(GLuint program, GLuint index,
     43                        GLsizei maxLength, GLsizei *length, GLint *size,
     44                        GLenum *type, GLcharARB *nameOut)
     45 {
     46    GET_CURRENT_CONTEXT(ctx);
     47    struct gl_shader_program *shProg;
     48    struct gl_program_resource *res;
     49 
     50    if (maxLength < 0) {
     51       _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(maxLength < 0)");
     52       return;
     53    }
     54 
     55    shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
     56    if (!shProg)
     57       return;
     58 
     59    res = _mesa_program_resource_find_index((struct gl_shader_program *) shProg,
     60                                            GL_UNIFORM, index);
     61 
     62    if (!res) {
     63       _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
     64       return;
     65    }
     66 
     67    if (nameOut)
     68       _mesa_get_program_resource_name(shProg, GL_UNIFORM, index, maxLength,
     69                                       length, nameOut, "glGetActiveUniform");
     70    if (type)
     71       _mesa_program_resource_prop((struct gl_shader_program *) shProg,
     72                                   res, index, GL_TYPE, (GLint*) type,
     73                                   "glGetActiveUniform");
     74    if (size)
     75       _mesa_program_resource_prop((struct gl_shader_program *) shProg,
     76                                   res, index, GL_ARRAY_SIZE, (GLint*) size,
     77                                   "glGetActiveUniform");
     78 }
     79 
     80 static GLenum
     81 resource_prop_from_uniform_prop(GLenum uni_prop)
     82 {
     83    switch (uni_prop) {
     84    case GL_UNIFORM_TYPE:
     85       return GL_TYPE;
     86    case GL_UNIFORM_SIZE:
     87       return GL_ARRAY_SIZE;
     88    case GL_UNIFORM_NAME_LENGTH:
     89       return GL_NAME_LENGTH;
     90    case GL_UNIFORM_BLOCK_INDEX:
     91       return GL_BLOCK_INDEX;
     92    case GL_UNIFORM_OFFSET:
     93       return GL_OFFSET;
     94    case GL_UNIFORM_ARRAY_STRIDE:
     95       return GL_ARRAY_STRIDE;
     96    case GL_UNIFORM_MATRIX_STRIDE:
     97       return GL_MATRIX_STRIDE;
     98    case GL_UNIFORM_IS_ROW_MAJOR:
     99       return GL_IS_ROW_MAJOR;
    100    case GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX:
    101       return GL_ATOMIC_COUNTER_BUFFER_INDEX;
    102    default:
    103       return 0;
    104    }
    105 }
    106 
    107 extern "C" void GLAPIENTRY
    108 _mesa_GetActiveUniformsiv(GLuint program,
    109 			  GLsizei uniformCount,
    110 			  const GLuint *uniformIndices,
    111 			  GLenum pname,
    112 			  GLint *params)
    113 {
    114    GET_CURRENT_CONTEXT(ctx);
    115    struct gl_shader_program *shProg;
    116    struct gl_program_resource *res;
    117    GLenum res_prop;
    118 
    119    if (uniformCount < 0) {
    120       _mesa_error(ctx, GL_INVALID_VALUE,
    121 		  "glGetActiveUniformsiv(uniformCount < 0)");
    122       return;
    123    }
    124 
    125    shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
    126    if (!shProg)
    127       return;
    128 
    129    res_prop = resource_prop_from_uniform_prop(pname);
    130 
    131    /* We need to first verify that each entry exists as active uniform. If
    132     * not, generate error and do not cause any other side effects.
    133     *
    134     * In the case of and error condition, Page 16 (section 2.3.1 Errors)
    135     * of the OpenGL 4.5 spec says:
    136     *
    137     *     "If the generating command modifies values through a pointer argu-
    138     *     ment, no change is made to these values."
    139     */
    140    for (int i = 0; i < uniformCount; i++) {
    141       if (!_mesa_program_resource_find_index(shProg, GL_UNIFORM,
    142                                               uniformIndices[i])) {
    143          _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)");
    144          return;
    145       }
    146    }
    147 
    148    for (int i = 0; i < uniformCount; i++) {
    149       res = _mesa_program_resource_find_index(shProg, GL_UNIFORM,
    150                                               uniformIndices[i]);
    151       if (!_mesa_program_resource_prop(shProg, res, uniformIndices[i],
    152                                        res_prop, &params[i],
    153                                        "glGetActiveUniformsiv"))
    154          break;
    155    }
    156 }
    157 
    158 static struct gl_uniform_storage *
    159 validate_uniform_parameters(struct gl_context *ctx,
    160 			    struct gl_shader_program *shProg,
    161 			    GLint location, GLsizei count,
    162 			    unsigned *array_index,
    163 			    const char *caller)
    164 {
    165    if (shProg == NULL) {
    166       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", caller);
    167       return NULL;
    168    }
    169 
    170    /* From page 12 (page 26 of the PDF) of the OpenGL 2.1 spec:
    171     *
    172     *     "If a negative number is provided where an argument of type sizei or
    173     *     sizeiptr is specified, the error INVALID_VALUE is generated."
    174     */
    175    if (count < 0) {
    176       _mesa_error(ctx, GL_INVALID_VALUE, "%s(count < 0)", caller);
    177       return NULL;
    178    }
    179 
    180    /* Check that the given location is in bounds of uniform remap table.
    181     * Unlinked programs will have NumUniformRemapTable == 0, so we can take
    182     * the shProg->data->LinkStatus check out of the main path.
    183     */
    184    if (unlikely(location >= (GLint) shProg->NumUniformRemapTable)) {
    185       if (!shProg->data->LinkStatus)
    186          _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)",
    187                      caller);
    188       else
    189          _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
    190                      caller, location);
    191 
    192       return NULL;
    193    }
    194 
    195    if (location == -1) {
    196       if (!shProg->data->LinkStatus)
    197          _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)",
    198                      caller);
    199 
    200       return NULL;
    201    }
    202 
    203    /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
    204     *
    205     *     "If any of the following conditions occur, an INVALID_OPERATION
    206     *     error is generated by the Uniform* commands, and no uniform values
    207     *     are changed:
    208     *
    209     *     ...
    210     *
    211     *         - if no variable with a location of location exists in the
    212     *           program object currently in use and location is not -1,
    213     *         - if count is greater than one, and the uniform declared in the
    214     *           shader is not an array variable,
    215     */
    216    if (location < -1 || !shProg->UniformRemapTable[location]) {
    217       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
    218                   caller, location);
    219       return NULL;
    220    }
    221 
    222    /* If the driver storage pointer in remap table is -1, we ignore silently.
    223     *
    224     * GL_ARB_explicit_uniform_location spec says:
    225     *     "What happens if Uniform* is called with an explicitly defined
    226     *     uniform location, but that uniform is deemed inactive by the
    227     *     linker?
    228     *
    229     *     RESOLVED: The call is ignored for inactive uniform variables and
    230     *     no error is generated."
    231     *
    232     */
    233    if (shProg->UniformRemapTable[location] ==
    234        INACTIVE_UNIFORM_EXPLICIT_LOCATION)
    235       return NULL;
    236 
    237    struct gl_uniform_storage *const uni = shProg->UniformRemapTable[location];
    238 
    239    /* Even though no location is assigned to a built-in uniform and this
    240     * function should already have returned NULL, this test makes it explicit
    241     * that we are not allowing to update the value of a built-in.
    242     */
    243    if (uni->builtin)
    244       return NULL;
    245 
    246    if (uni->array_elements == 0) {
    247       if (count > 1) {
    248          _mesa_error(ctx, GL_INVALID_OPERATION,
    249                      "%s(count = %u for non-array \"%s\"@%d)",
    250                      caller, count, uni->name, location);
    251          return NULL;
    252       }
    253 
    254       assert((location - uni->remap_location) == 0);
    255       *array_index = 0;
    256    } else {
    257       /* The array index specified by the uniform location is just the uniform
    258        * location minus the base location of of the uniform.
    259        */
    260       *array_index = location - uni->remap_location;
    261 
    262       /* If the uniform is an array, check that array_index is in bounds.
    263        * array_index is unsigned so no need to check for less than zero.
    264        */
    265       if (*array_index >= uni->array_elements) {
    266          _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
    267                      caller, location);
    268          return NULL;
    269       }
    270    }
    271    return uni;
    272 }
    273 
    274 /**
    275  * Called via glGetUniform[fiui]v() to get the current value of a uniform.
    276  */
    277 extern "C" void
    278 _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
    279 		  GLsizei bufSize, enum glsl_base_type returnType,
    280 		  GLvoid *paramsOut)
    281 {
    282    struct gl_shader_program *shProg =
    283       _mesa_lookup_shader_program_err(ctx, program, "glGetUniformfv");
    284    unsigned offset;
    285 
    286    struct gl_uniform_storage *const uni =
    287       validate_uniform_parameters(ctx, shProg, location, 1,
    288                                   &offset, "glGetUniform");
    289    if (uni == NULL) {
    290       /* For glGetUniform, page 264 (page 278 of the PDF) of the OpenGL 2.1
    291        * spec says:
    292        *
    293        *     "The error INVALID_OPERATION is generated if program has not been
    294        *     linked successfully, or if location is not a valid location for
    295        *     program."
    296        *
    297        * For glUniform, page 82 (page 96 of the PDF) of the OpenGL 2.1 spec
    298        * says:
    299        *
    300        *     "If the value of location is -1, the Uniform* commands will
    301        *     silently ignore the data passed in, and the current uniform
    302        *     values will not be changed."
    303        *
    304        * Allowing -1 for the location parameter of glUniform allows
    305        * applications to avoid error paths in the case that, for example, some
    306        * uniform variable is removed by the compiler / linker after
    307        * optimization.  In this case, the new value of the uniform is dropped
    308        * on the floor.  For the case of glGetUniform, there is nothing
    309        * sensible to do for a location of -1.
    310        *
    311        * If the location was -1, validate_unfirom_parameters will return NULL
    312        * without raising an error.  Raise the error here.
    313        */
    314       if (location == -1) {
    315          _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniform(location=%d)",
    316                      location);
    317       }
    318 
    319       return;
    320    }
    321 
    322    {
    323       unsigned elements = (uni->type->is_sampler())
    324 	 ? 1 : uni->type->components();
    325       const int dmul = uni->type->is_64bit() ? 2 : 1;
    326       const int rmul = glsl_base_type_is_64bit(returnType) ? 2 : 1;
    327 
    328       /* Calculate the source base address *BEFORE* modifying elements to
    329        * account for the size of the user's buffer.
    330        */
    331       const union gl_constant_value *const src =
    332 	 &uni->storage[offset * elements * dmul];
    333 
    334       assert(returnType == GLSL_TYPE_FLOAT || returnType == GLSL_TYPE_INT ||
    335              returnType == GLSL_TYPE_UINT || returnType == GLSL_TYPE_DOUBLE);
    336 
    337       /* doubles have a different size than the other 3 types */
    338       unsigned bytes = sizeof(src[0]) * elements * rmul;
    339       if (bufSize < 0 || bytes > (unsigned) bufSize) {
    340 	 _mesa_error( ctx, GL_INVALID_OPERATION,
    341 	             "glGetnUniform*vARB(out of bounds: bufSize is %d,"
    342 	             " but %u bytes are required)", bufSize, bytes );
    343 	 return;
    344       }
    345 
    346       /* If the return type and the uniform's native type are "compatible,"
    347        * just memcpy the data.  If the types are not compatible, perform a
    348        * slower convert-and-copy process.
    349        */
    350       if (returnType == uni->type->base_type
    351 	  || ((returnType == GLSL_TYPE_INT
    352 	       || returnType == GLSL_TYPE_UINT)
    353 	      &&
    354 	      (uni->type->base_type == GLSL_TYPE_INT
    355 	       || uni->type->base_type == GLSL_TYPE_UINT
    356                || uni->type->base_type == GLSL_TYPE_SAMPLER
    357                || uni->type->base_type == GLSL_TYPE_IMAGE))) {
    358 	 memcpy(paramsOut, src, bytes);
    359       } else {
    360 	 union gl_constant_value *const dst =
    361 	    (union gl_constant_value *) paramsOut;
    362 	 /* This code could be optimized by putting the loop inside the switch
    363 	  * statements.  However, this is not expected to be
    364 	  * performance-critical code.
    365 	  */
    366 	 for (unsigned i = 0; i < elements; i++) {
    367 	   int sidx = i * dmul;
    368 	   int didx = i * rmul;
    369 
    370 	    switch (returnType) {
    371 	    case GLSL_TYPE_FLOAT:
    372 	       switch (uni->type->base_type) {
    373 	       case GLSL_TYPE_UINT:
    374 		  dst[didx].f = (float) src[sidx].u;
    375 		  break;
    376 	       case GLSL_TYPE_INT:
    377 	       case GLSL_TYPE_SAMPLER:
    378                case GLSL_TYPE_IMAGE:
    379 		  dst[didx].f = (float) src[sidx].i;
    380 		  break;
    381 	       case GLSL_TYPE_BOOL:
    382 		  dst[didx].f = src[sidx].i ? 1.0f : 0.0f;
    383 		  break;
    384                case GLSL_TYPE_DOUBLE: {
    385                   double tmp;
    386                   memcpy(&tmp, &src[sidx].f, sizeof(tmp));
    387                   dst[didx].f = tmp;
    388 		  break;
    389                }
    390 	       default:
    391 		  assert(!"Should not get here.");
    392 		  break;
    393 	       }
    394 	       break;
    395 	    case GLSL_TYPE_DOUBLE:
    396 	       switch (uni->type->base_type) {
    397                case GLSL_TYPE_UINT: {
    398                   double tmp = src[sidx].u;
    399                   memcpy(&dst[didx].f, &tmp, sizeof(tmp));
    400 		  break;
    401                }
    402 	       case GLSL_TYPE_INT:
    403 	       case GLSL_TYPE_SAMPLER:
    404                case GLSL_TYPE_IMAGE: {
    405                   double tmp = src[sidx].i;
    406                   memcpy(&dst[didx].f, &tmp, sizeof(tmp));
    407 		  break;
    408                }
    409                case GLSL_TYPE_BOOL: {
    410                   double tmp = src[sidx].i ? 1.0 : 0.0;
    411                   memcpy(&dst[didx].f, &tmp, sizeof(tmp));
    412 		  break;
    413                }
    414                case GLSL_TYPE_FLOAT: {
    415                   double tmp = src[sidx].f;
    416                   memcpy(&dst[didx].f, &tmp, sizeof(tmp));
    417 		  break;
    418                }
    419 	       default:
    420 		  assert(!"Should not get here.");
    421 		  break;
    422 	       }
    423 	       break;
    424 	    case GLSL_TYPE_INT:
    425 	    case GLSL_TYPE_UINT:
    426 	       switch (uni->type->base_type) {
    427 	       case GLSL_TYPE_FLOAT:
    428 		  /* While the GL 3.2 core spec doesn't explicitly
    429 		   * state how conversion of float uniforms to integer
    430 		   * values works, in section 6.2 "State Tables" on
    431 		   * page 267 it says:
    432 		   *
    433 		   *     "Unless otherwise specified, when floating
    434 		   *      point state is returned as integer values or
    435 		   *      integer state is returned as floating-point
    436 		   *      values it is converted in the fashion
    437 		   *      described in section 6.1.2"
    438 		   *
    439 		   * That section, on page 248, says:
    440 		   *
    441 		   *     "If GetIntegerv or GetInteger64v are called,
    442 		   *      a floating-point value is rounded to the
    443 		   *      nearest integer..."
    444 		   */
    445 		  dst[didx].i = IROUND(src[sidx].f);
    446 		  break;
    447 	       case GLSL_TYPE_BOOL:
    448 		  dst[didx].i = src[sidx].i ? 1 : 0;
    449 		  break;
    450                case GLSL_TYPE_DOUBLE: {
    451                   double tmp;
    452                   memcpy(&tmp, &src[sidx].f, sizeof(tmp));
    453                   dst[didx].i = IROUNDD(tmp);
    454 		  break;
    455                }
    456 	       default:
    457 		  assert(!"Should not get here.");
    458 		  break;
    459 	       }
    460 	       break;
    461 
    462 	    default:
    463 	       assert(!"Should not get here.");
    464 	       break;
    465 	    }
    466 	 }
    467       }
    468    }
    469 }
    470 
    471 static void
    472 log_uniform(const void *values, enum glsl_base_type basicType,
    473 	    unsigned rows, unsigned cols, unsigned count,
    474 	    bool transpose,
    475 	    const struct gl_shader_program *shProg,
    476 	    GLint location,
    477 	    const struct gl_uniform_storage *uni)
    478 {
    479 
    480    const union gl_constant_value *v = (const union gl_constant_value *) values;
    481    const unsigned elems = rows * cols * count;
    482    const char *const extra = (cols == 1) ? "uniform" : "uniform matrix";
    483 
    484    printf("Mesa: set program %u %s \"%s\" (loc %d, type \"%s\", "
    485 	  "transpose = %s) to: ",
    486 	  shProg->Name, extra, uni->name, location, uni->type->name,
    487 	  transpose ? "true" : "false");
    488    for (unsigned i = 0; i < elems; i++) {
    489       if (i != 0 && ((i % rows) == 0))
    490 	 printf(", ");
    491 
    492       switch (basicType) {
    493       case GLSL_TYPE_UINT:
    494 	 printf("%u ", v[i].u);
    495 	 break;
    496       case GLSL_TYPE_INT:
    497 	 printf("%d ", v[i].i);
    498 	 break;
    499       case GLSL_TYPE_FLOAT:
    500 	 printf("%g ", v[i].f);
    501 	 break;
    502       case GLSL_TYPE_DOUBLE: {
    503          double tmp;
    504          memcpy(&tmp, &v[i * 2].f, sizeof(tmp));
    505          printf("%g ", tmp);
    506          break;
    507       }
    508       default:
    509 	 assert(!"Should not get here.");
    510 	 break;
    511       }
    512    }
    513    printf("\n");
    514    fflush(stdout);
    515 }
    516 
    517 #if 0
    518 static void
    519 log_program_parameters(const struct gl_shader_program *shProg)
    520 {
    521    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
    522       if (shProg->_LinkedShaders[i] == NULL)
    523 	 continue;
    524 
    525       const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program;
    526 
    527       printf("Program %d %s shader parameters:\n",
    528              shProg->Name, _mesa_shader_stage_to_string(i));
    529       for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) {
    530 	 printf("%s: %p %f %f %f %f\n",
    531 		prog->Parameters->Parameters[j].Name,
    532 		prog->Parameters->ParameterValues[j],
    533 		prog->Parameters->ParameterValues[j][0].f,
    534 		prog->Parameters->ParameterValues[j][1].f,
    535 		prog->Parameters->ParameterValues[j][2].f,
    536 		prog->Parameters->ParameterValues[j][3].f);
    537       }
    538    }
    539    fflush(stdout);
    540 }
    541 #endif
    542 
    543 /**
    544  * Propagate some values from uniform backing storage to driver storage
    545  *
    546  * Values propagated from uniform backing storage to driver storage
    547  * have all format / type conversions previously requested by the
    548  * driver applied.  This function is most often called by the
    549  * implementations of \c glUniform1f, etc. and \c glUniformMatrix2f,
    550  * etc.
    551  *
    552  * \param uni          Uniform whose data is to be propagated to driver storage
    553  * \param array_index  If \c uni is an array, this is the element of
    554  *                     the array to be propagated.
    555  * \param count        Number of array elements to propagate.
    556  */
    557 extern "C" void
    558 _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni,
    559 					   unsigned array_index,
    560 					   unsigned count)
    561 {
    562    unsigned i;
    563 
    564    /* vector_elements and matrix_columns can be 0 for samplers.
    565     */
    566    const unsigned components = MAX2(1, uni->type->vector_elements);
    567    const unsigned vectors = MAX2(1, uni->type->matrix_columns);
    568    const int dmul = uni->type->is_64bit() ? 2 : 1;
    569 
    570    /* Store the data in the driver's requested type in the driver's storage
    571     * areas.
    572     */
    573    unsigned src_vector_byte_stride = components * 4 * dmul;
    574 
    575    for (i = 0; i < uni->num_driver_storage; i++) {
    576       struct gl_uniform_driver_storage *const store = &uni->driver_storage[i];
    577       uint8_t *dst = (uint8_t *) store->data;
    578       const unsigned extra_stride =
    579 	 store->element_stride - (vectors * store->vector_stride);
    580       const uint8_t *src =
    581 	 (uint8_t *) (&uni->storage[array_index * (dmul * components * vectors)].i);
    582 
    583 #if 0
    584       printf("%s: %p[%d] components=%u vectors=%u count=%u vector_stride=%u "
    585 	     "extra_stride=%u\n",
    586 	     __func__, dst, array_index, components,
    587 	     vectors, count, store->vector_stride, extra_stride);
    588 #endif
    589 
    590       dst += array_index * store->element_stride;
    591 
    592       switch (store->format) {
    593       case uniform_native: {
    594 	 unsigned j;
    595 	 unsigned v;
    596 
    597 	 if (src_vector_byte_stride == store->vector_stride) {
    598 	    if (extra_stride) {
    599 	       for (j = 0; j < count; j++) {
    600 	          memcpy(dst, src, src_vector_byte_stride * vectors);
    601 	          src += src_vector_byte_stride * vectors;
    602 	          dst += store->vector_stride * vectors;
    603 
    604 	          dst += extra_stride;
    605 	       }
    606 	    } else {
    607 	       /* Unigine Heaven benchmark gets here */
    608 	       memcpy(dst, src, src_vector_byte_stride * vectors * count);
    609 	       src += src_vector_byte_stride * vectors * count;
    610 	       dst += store->vector_stride * vectors * count;
    611 	    }
    612 	 } else {
    613 	    for (j = 0; j < count; j++) {
    614 	       for (v = 0; v < vectors; v++) {
    615 	          memcpy(dst, src, src_vector_byte_stride);
    616 	          src += src_vector_byte_stride;
    617 	          dst += store->vector_stride;
    618 	       }
    619 
    620 	       dst += extra_stride;
    621 	    }
    622 	 }
    623 	 break;
    624       }
    625 
    626       case uniform_int_float: {
    627 	 const int *isrc = (const int *) src;
    628 	 unsigned j;
    629 	 unsigned v;
    630 	 unsigned c;
    631 
    632 	 for (j = 0; j < count; j++) {
    633 	    for (v = 0; v < vectors; v++) {
    634 	       for (c = 0; c < components; c++) {
    635 		  ((float *) dst)[c] = (float) *isrc;
    636 		  isrc++;
    637 	       }
    638 
    639 	       dst += store->vector_stride;
    640 	    }
    641 
    642 	    dst += extra_stride;
    643 	 }
    644 	 break;
    645       }
    646 
    647       default:
    648 	 assert(!"Should not get here.");
    649 	 break;
    650       }
    651    }
    652 }
    653 
    654 
    655 /**
    656  * Return printable string for a given GLSL_TYPE_x
    657  */
    658 static const char *
    659 glsl_type_name(enum glsl_base_type type)
    660 {
    661    switch (type) {
    662    case GLSL_TYPE_UINT:
    663       return "uint";
    664    case GLSL_TYPE_INT:
    665       return "int";
    666    case GLSL_TYPE_FLOAT:
    667       return "float";
    668    case GLSL_TYPE_DOUBLE:
    669       return "double";
    670    case GLSL_TYPE_BOOL:
    671       return "bool";
    672    case GLSL_TYPE_SAMPLER:
    673       return "sampler";
    674    case GLSL_TYPE_IMAGE:
    675       return "image";
    676    case GLSL_TYPE_ATOMIC_UINT:
    677       return "atomic_uint";
    678    case GLSL_TYPE_STRUCT:
    679       return "struct";
    680    case GLSL_TYPE_INTERFACE:
    681       return "interface";
    682    case GLSL_TYPE_ARRAY:
    683       return "array";
    684    case GLSL_TYPE_VOID:
    685       return "void";
    686    case GLSL_TYPE_ERROR:
    687       return "error";
    688    default:
    689       return "other";
    690    }
    691 }
    692 
    693 
    694 /**
    695  * Called via glUniform*() functions.
    696  */
    697 extern "C" void
    698 _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
    699 	      GLint location, GLsizei count,
    700               const GLvoid *values,
    701               enum glsl_base_type basicType,
    702               unsigned src_components)
    703 {
    704    unsigned offset;
    705    int size_mul = glsl_base_type_is_64bit(basicType) ? 2 : 1;
    706 
    707    struct gl_uniform_storage *const uni =
    708       validate_uniform_parameters(ctx, shProg, location, count,
    709                                   &offset, "glUniform");
    710    if (uni == NULL)
    711       return;
    712 
    713    if (uni->type->is_matrix()) {
    714       /* Can't set matrix uniforms (like mat4) with glUniform */
    715       _mesa_error(ctx, GL_INVALID_OPERATION,
    716                   "glUniform%u(uniform \"%s\"@%d is matrix)",
    717                   src_components, uni->name, location);
    718       return;
    719    }
    720 
    721    /* Verify that the types are compatible.
    722     */
    723    const unsigned components = uni->type->is_sampler()
    724       ? 1 : uni->type->vector_elements;
    725 
    726    if (components != src_components) {
    727       /* glUniformN() must match float/vecN type */
    728       _mesa_error(ctx, GL_INVALID_OPERATION,
    729                   "glUniform%u(\"%s\"@%u has %u components, not %u)",
    730                   src_components, uni->name, location,
    731                   components, src_components);
    732       return;
    733    }
    734 
    735    bool match;
    736    switch (uni->type->base_type) {
    737    case GLSL_TYPE_BOOL:
    738       match = (basicType != GLSL_TYPE_DOUBLE);
    739       break;
    740    case GLSL_TYPE_SAMPLER:
    741       match = (basicType == GLSL_TYPE_INT);
    742       break;
    743    case GLSL_TYPE_IMAGE:
    744       match = (basicType == GLSL_TYPE_INT && _mesa_is_desktop_gl(ctx));
    745       break;
    746    default:
    747       match = (basicType == uni->type->base_type);
    748       break;
    749    }
    750 
    751    if (!match) {
    752       _mesa_error(ctx, GL_INVALID_OPERATION,
    753                   "glUniform%u(\"%s\"@%d is %s, not %s)",
    754                   src_components, uni->name, location,
    755                   glsl_type_name(uni->type->base_type),
    756                   glsl_type_name(basicType));
    757       return;
    758    }
    759 
    760    if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
    761       log_uniform(values, basicType, components, 1, count,
    762 		  false, shProg, location, uni);
    763    }
    764 
    765    /* Page 100 (page 116 of the PDF) of the OpenGL 3.0 spec says:
    766     *
    767     *     "Setting a sampler's value to i selects texture image unit number
    768     *     i. The values of i range from zero to the implementation- dependent
    769     *     maximum supported number of texture image units."
    770     *
    771     * In addition, table 2.3, "Summary of GL errors," on page 17 (page 33 of
    772     * the PDF) says:
    773     *
    774     *     "Error         Description                    Offending command
    775     *                                                   ignored?
    776     *     ...
    777     *     INVALID_VALUE  Numeric argument out of range  Yes"
    778     *
    779     * Based on that, when an invalid sampler is specified, we generate a
    780     * GL_INVALID_VALUE error and ignore the command.
    781     */
    782    if (uni->type->is_sampler()) {
    783       for (int i = 0; i < count; i++) {
    784 	 const unsigned texUnit = ((unsigned *) values)[i];
    785 
    786          /* check that the sampler (tex unit index) is legal */
    787          if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
    788             _mesa_error(ctx, GL_INVALID_VALUE,
    789                         "glUniform1i(invalid sampler/tex unit index for "
    790 			"uniform %d)",
    791                         location);
    792             return;
    793          }
    794       }
    795       /* We need to reset the validate flag on changes to samplers in case
    796        * two different sampler types are set to the same texture unit.
    797        */
    798       ctx->_Shader->Validated = GL_FALSE;
    799    }
    800 
    801    if (uni->type->is_image()) {
    802       for (int i = 0; i < count; i++) {
    803          const int unit = ((GLint *) values)[i];
    804 
    805          /* check that the image unit is legal */
    806          if (unit < 0 || unit >= (int)ctx->Const.MaxImageUnits) {
    807             _mesa_error(ctx, GL_INVALID_VALUE,
    808                         "glUniform1i(invalid image unit index for uniform %d)",
    809                         location);
    810             return;
    811          }
    812       }
    813    }
    814 
    815    /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
    816     *
    817     *     "When loading N elements starting at an arbitrary position k in a
    818     *     uniform declared as an array, elements k through k + N - 1 in the
    819     *     array will be replaced with the new values. Values for any array
    820     *     element that exceeds the highest array element index used, as
    821     *     reported by GetActiveUniform, will be ignored by the GL."
    822     *
    823     * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
    824     * will have already generated an error.
    825     */
    826    if (uni->array_elements != 0) {
    827       count = MIN2(count, (int) (uni->array_elements - offset));
    828    }
    829 
    830    FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
    831 
    832    /* Store the data in the "actual type" backing storage for the uniform.
    833     */
    834    if (!uni->type->is_boolean()) {
    835       memcpy(&uni->storage[size_mul * components * offset], values,
    836 	     sizeof(uni->storage[0]) * components * count * size_mul);
    837    } else {
    838       const union gl_constant_value *src =
    839 	 (const union gl_constant_value *) values;
    840       union gl_constant_value *dst = &uni->storage[components * offset];
    841       const unsigned elems = components * count;
    842 
    843       for (unsigned i = 0; i < elems; i++) {
    844 	 if (basicType == GLSL_TYPE_FLOAT) {
    845             dst[i].i = src[i].f != 0.0f ? ctx->Const.UniformBooleanTrue : 0;
    846 	 } else {
    847             dst[i].i = src[i].i != 0    ? ctx->Const.UniformBooleanTrue : 0;
    848 	 }
    849       }
    850    }
    851 
    852    _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
    853 
    854    /* If the uniform is a sampler, do the extra magic necessary to propagate
    855     * the changes through.
    856     */
    857    if (uni->type->is_sampler()) {
    858       bool flushed = false;
    859       for (int i = 0; i < MESA_SHADER_STAGES; i++) {
    860 	 struct gl_linked_shader *const sh = shProg->_LinkedShaders[i];
    861 
    862 	 /* If the shader stage doesn't use the sampler uniform, skip this. */
    863 	 if (!uni->opaque[i].active)
    864 	    continue;
    865 
    866          bool changed = false;
    867          for (int j = 0; j < count; j++) {
    868             unsigned unit = uni->opaque[i].index + offset + j;
    869             if (sh->Program->SamplerUnits[unit] != ((unsigned *) values)[j]) {
    870                sh->Program->SamplerUnits[unit] = ((unsigned *) values)[j];
    871                changed = true;
    872             }
    873          }
    874 
    875 	 if (changed) {
    876 	    if (!flushed) {
    877 	       FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
    878 	       flushed = true;
    879 	    }
    880 
    881             struct gl_program *const prog = sh->Program;
    882 	    _mesa_update_shader_textures_used(shProg, prog);
    883             if (ctx->Driver.SamplerUniformChange)
    884 	       ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog);
    885 	 }
    886       }
    887    }
    888 
    889    /* If the uniform is an image, update the mapping from image
    890     * uniforms to image units present in the shader data structure.
    891     */
    892    if (uni->type->is_image()) {
    893       for (int i = 0; i < MESA_SHADER_STAGES; i++) {
    894 	 if (uni->opaque[i].active) {
    895             struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
    896 
    897             for (int j = 0; j < count; j++)
    898                sh->Program->sh.ImageUnits[uni->opaque[i].index + offset + j] =
    899                   ((GLint *) values)[j];
    900          }
    901       }
    902 
    903       ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;
    904    }
    905 }
    906 
    907 /**
    908  * Called by glUniformMatrix*() functions.
    909  * Note: cols=2, rows=4  ==>  array[2] of vec4
    910  */
    911 extern "C" void
    912 _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
    913 		     GLuint cols, GLuint rows,
    914                      GLint location, GLsizei count,
    915                      GLboolean transpose,
    916                      const GLvoid *values, enum glsl_base_type basicType)
    917 {
    918    unsigned offset;
    919    unsigned vectors;
    920    unsigned components;
    921    unsigned elements;
    922    int size_mul;
    923    struct gl_uniform_storage *const uni =
    924       validate_uniform_parameters(ctx, shProg, location, count,
    925                                   &offset, "glUniformMatrix");
    926    if (uni == NULL)
    927       return;
    928 
    929    if (!uni->type->is_matrix()) {
    930       _mesa_error(ctx, GL_INVALID_OPERATION,
    931 		  "glUniformMatrix(non-matrix uniform)");
    932       return;
    933    }
    934 
    935    assert(basicType == GLSL_TYPE_FLOAT || basicType == GLSL_TYPE_DOUBLE);
    936    size_mul = basicType == GLSL_TYPE_DOUBLE ? 2 : 1;
    937 
    938    assert(!uni->type->is_sampler());
    939    vectors = uni->type->matrix_columns;
    940    components = uni->type->vector_elements;
    941 
    942    /* Verify that the types are compatible.  This is greatly simplified for
    943     * matrices because they can only have a float base type.
    944     */
    945    if (vectors != cols || components != rows) {
    946       _mesa_error(ctx, GL_INVALID_OPERATION,
    947 		  "glUniformMatrix(matrix size mismatch)");
    948       return;
    949    }
    950 
    951    /* GL_INVALID_VALUE is generated if `transpose' is not GL_FALSE.
    952     * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml
    953     */
    954    if (transpose) {
    955       if (ctx->API == API_OPENGLES2 && ctx->Version < 30) {
    956 	 _mesa_error(ctx, GL_INVALID_VALUE,
    957 		     "glUniformMatrix(matrix transpose is not GL_FALSE)");
    958 	 return;
    959       }
    960    }
    961 
    962    /* Section 2.11.7 (Uniform Variables) of the OpenGL 4.2 Core Profile spec
    963     * says:
    964     *
    965     *     "If any of the following conditions occur, an INVALID_OPERATION
    966     *     error is generated by the Uniform* commands, and no uniform values
    967     *     are changed:
    968     *
    969     *     ...
    970     *
    971     *     - if the uniform declared in the shader is not of type boolean and
    972     *       the type indicated in the name of the Uniform* command used does
    973     *       not match the type of the uniform"
    974     *
    975     * There are no Boolean matrix types, so we do not need to allow
    976     * GLSL_TYPE_BOOL here (as _mesa_uniform does).
    977     */
    978    if (uni->type->base_type != basicType) {
    979       _mesa_error(ctx, GL_INVALID_OPERATION,
    980                   "glUniformMatrix%ux%u(\"%s\"@%d is %s, not %s)",
    981                   cols, rows, uni->name, location,
    982                   glsl_type_name(uni->type->base_type),
    983                   glsl_type_name(basicType));
    984       return;
    985    }
    986 
    987    if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
    988       log_uniform(values, uni->type->base_type, components, vectors, count,
    989 		  bool(transpose), shProg, location, uni);
    990    }
    991 
    992    /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
    993     *
    994     *     "When loading N elements starting at an arbitrary position k in a
    995     *     uniform declared as an array, elements k through k + N - 1 in the
    996     *     array will be replaced with the new values. Values for any array
    997     *     element that exceeds the highest array element index used, as
    998     *     reported by GetActiveUniform, will be ignored by the GL."
    999     *
   1000     * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
   1001     * will have already generated an error.
   1002     */
   1003    if (uni->array_elements != 0) {
   1004       count = MIN2(count, (int) (uni->array_elements - offset));
   1005    }
   1006 
   1007    FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
   1008 
   1009    /* Store the data in the "actual type" backing storage for the uniform.
   1010     */
   1011    elements = components * vectors;
   1012 
   1013    if (!transpose) {
   1014       memcpy(&uni->storage[size_mul * elements * offset], values,
   1015 	     sizeof(uni->storage[0]) * elements * count * size_mul);
   1016    } else if (basicType == GLSL_TYPE_FLOAT) {
   1017       /* Copy and transpose the matrix.
   1018        */
   1019       const float *src = (const float *)values;
   1020       float *dst = &uni->storage[elements * offset].f;
   1021 
   1022       for (int i = 0; i < count; i++) {
   1023 	 for (unsigned r = 0; r < rows; r++) {
   1024 	    for (unsigned c = 0; c < cols; c++) {
   1025 	       dst[(c * components) + r] = src[c + (r * vectors)];
   1026 	    }
   1027 	 }
   1028 
   1029 	 dst += elements;
   1030 	 src += elements;
   1031       }
   1032    } else {
   1033       assert(basicType == GLSL_TYPE_DOUBLE);
   1034       const double *src = (const double *)values;
   1035       double *dst = (double *)&uni->storage[elements * offset].f;
   1036 
   1037       for (int i = 0; i < count; i++) {
   1038 	 for (unsigned r = 0; r < rows; r++) {
   1039 	    for (unsigned c = 0; c < cols; c++) {
   1040 	       dst[(c * components) + r] = src[c + (r * vectors)];
   1041 	    }
   1042 	 }
   1043 
   1044 	 dst += elements;
   1045 	 src += elements;
   1046       }
   1047    }
   1048 
   1049    _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
   1050 }
   1051 
   1052 
   1053 extern "C" bool
   1054 _mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
   1055 				 char *errMsg, size_t errMsgLength)
   1056 {
   1057    /* Shader does not have samplers. */
   1058    if (shProg->data->NumUniformStorage == 0)
   1059       return true;
   1060 
   1061    if (!shProg->SamplersValidated) {
   1062       _mesa_snprintf(errMsg, errMsgLength,
   1063                      "active samplers with a different type "
   1064                      "refer to the same texture image unit");
   1065       return false;
   1066    }
   1067    return true;
   1068 }
   1069 
   1070 extern "C" bool
   1071 _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline)
   1072 {
   1073    /* Section 2.11.11 (Shader Execution), subheading "Validation," of the
   1074     * OpenGL 4.1 spec says:
   1075     *
   1076     *     "[INVALID_OPERATION] is generated by any command that transfers
   1077     *     vertices to the GL if:
   1078     *
   1079     *         ...
   1080     *
   1081     *         - Any two active samplers in the current program object are of
   1082     *           different types, but refer to the same texture image unit.
   1083     *
   1084     *         - The number of active samplers in the program exceeds the
   1085     *           maximum number of texture image units allowed."
   1086     */
   1087 
   1088    GLbitfield mask;
   1089    GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
   1090    struct gl_linked_shader *shader;
   1091    unsigned active_samplers = 0;
   1092    const struct gl_shader_program **shProg =
   1093       (const struct gl_shader_program **) pipeline->CurrentProgram;
   1094 
   1095 
   1096    memset(TexturesUsed, 0, sizeof(TexturesUsed));
   1097 
   1098    for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
   1099       if (!shProg[idx])
   1100          continue;
   1101 
   1102       shader = shProg[idx]->_LinkedShaders[idx];
   1103       if (!shader || !shader->Program)
   1104          continue;
   1105 
   1106       mask = shader->Program->SamplersUsed;
   1107       while (mask) {
   1108          const int s = u_bit_scan(&mask);
   1109          GLuint unit = shader->Program->SamplerUnits[s];
   1110          GLuint tgt = shader->Program->sh.SamplerTargets[s];
   1111 
   1112          /* FIXME: Samplers are initialized to 0 and Mesa doesn't do a
   1113           * great job of eliminating unused uniforms currently so for now
   1114           * don't throw an error if two sampler types both point to 0.
   1115           */
   1116          if (unit == 0)
   1117             continue;
   1118 
   1119          if (TexturesUsed[unit] & ~(1 << tgt)) {
   1120             pipeline->InfoLog =
   1121                ralloc_asprintf(pipeline,
   1122                      "Program %d: "
   1123                      "Texture unit %d is accessed with 2 different types",
   1124                      shProg[idx]->Name, unit);
   1125             return false;
   1126          }
   1127 
   1128          TexturesUsed[unit] |= (1 << tgt);
   1129       }
   1130 
   1131       active_samplers += shader->Program->info.num_textures;
   1132    }
   1133 
   1134    if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) {
   1135       pipeline->InfoLog =
   1136          ralloc_asprintf(pipeline,
   1137                          "the number of active samplers %d exceed the "
   1138                          "maximum %d",
   1139                          active_samplers, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
   1140       return false;
   1141    }
   1142 
   1143    return true;
   1144 }
   1145