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