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