Subversion Repositories Kolibri OS

Rev

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