OSDN Git Service

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