Subversion Repositories Kolibri OS

Rev

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

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