uniform_query.cpp revision 7ec681f3
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#include <inttypes.h>  /* for PRIx64 macro */
29#include <math.h>
30
31#include "main/context.h"
32#include "main/draw_validate.h"
33#include "main/shaderapi.h"
34#include "main/shaderobj.h"
35#include "main/uniforms.h"
36#include "compiler/glsl/ir.h"
37#include "compiler/glsl/ir_uniform.h"
38#include "compiler/glsl/glsl_parser_extras.h"
39#include "compiler/glsl/program.h"
40#include "util/bitscan.h"
41
42
43/* This is one of the few glGet that can be called from the app thread safely.
44 * Only these conditions must be met:
45 * - There are no unfinished glLinkProgram and glDeleteProgram calls
46 *   for the program object. This assures that the program object is immutable.
47 * - glthread=true for GL errors to be passed to the driver thread safely
48 *
49 * Program objects can be looked up from any thread because they are part
50 * of the multi-context shared state.
51 */
52extern "C" void
53_mesa_GetActiveUniform_impl(GLuint program, GLuint index,
54                            GLsizei maxLength, GLsizei *length, GLint *size,
55                            GLenum *type, GLcharARB *nameOut, bool glthread)
56{
57   GET_CURRENT_CONTEXT(ctx);
58   struct gl_shader_program *shProg;
59   struct gl_program_resource *res;
60
61   if (maxLength < 0) {
62      _mesa_error_glthread_safe(ctx, GL_INVALID_VALUE, glthread,
63                                "glGetActiveUniform(maxLength < 0)");
64      return;
65   }
66
67   shProg = _mesa_lookup_shader_program_err_glthread(ctx, program, glthread,
68                                                     "glGetActiveUniform");
69   if (!shProg)
70      return;
71
72   res = _mesa_program_resource_find_index((struct gl_shader_program *) shProg,
73                                           GL_UNIFORM, index);
74
75   if (!res) {
76      _mesa_error_glthread_safe(ctx, GL_INVALID_VALUE, glthread,
77                                "glGetActiveUniform(index)");
78      return;
79   }
80
81   if (nameOut)
82      _mesa_get_program_resource_name(shProg, GL_UNIFORM, index, maxLength,
83                                      length, nameOut, glthread,
84                                      "glGetActiveUniform");
85   if (type)
86      _mesa_program_resource_prop((struct gl_shader_program *) shProg,
87                                  res, index, GL_TYPE, (GLint*) type,
88                                  glthread, "glGetActiveUniform");
89   if (size)
90      _mesa_program_resource_prop((struct gl_shader_program *) shProg,
91                                  res, index, GL_ARRAY_SIZE, (GLint*) size,
92                                  glthread, "glGetActiveUniform");
93}
94
95extern "C" void GLAPIENTRY
96_mesa_GetActiveUniform(GLuint program, GLuint index,
97                       GLsizei maxLength, GLsizei *length, GLint *size,
98                       GLenum *type, GLcharARB *nameOut)
99{
100   _mesa_GetActiveUniform_impl(program, index, maxLength, length, size,
101                               type, nameOut, false);
102}
103
104static GLenum
105resource_prop_from_uniform_prop(GLenum uni_prop)
106{
107   switch (uni_prop) {
108   case GL_UNIFORM_TYPE:
109      return GL_TYPE;
110   case GL_UNIFORM_SIZE:
111      return GL_ARRAY_SIZE;
112   case GL_UNIFORM_NAME_LENGTH:
113      return GL_NAME_LENGTH;
114   case GL_UNIFORM_BLOCK_INDEX:
115      return GL_BLOCK_INDEX;
116   case GL_UNIFORM_OFFSET:
117      return GL_OFFSET;
118   case GL_UNIFORM_ARRAY_STRIDE:
119      return GL_ARRAY_STRIDE;
120   case GL_UNIFORM_MATRIX_STRIDE:
121      return GL_MATRIX_STRIDE;
122   case GL_UNIFORM_IS_ROW_MAJOR:
123      return GL_IS_ROW_MAJOR;
124   case GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX:
125      return GL_ATOMIC_COUNTER_BUFFER_INDEX;
126   default:
127      return 0;
128   }
129}
130
131extern "C" void GLAPIENTRY
132_mesa_GetActiveUniformsiv(GLuint program,
133			  GLsizei uniformCount,
134			  const GLuint *uniformIndices,
135			  GLenum pname,
136			  GLint *params)
137{
138   GET_CURRENT_CONTEXT(ctx);
139   struct gl_shader_program *shProg;
140   struct gl_program_resource *res;
141   GLenum res_prop;
142
143   if (uniformCount < 0) {
144      _mesa_error(ctx, GL_INVALID_VALUE,
145		  "glGetActiveUniformsiv(uniformCount < 0)");
146      return;
147   }
148
149   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
150   if (!shProg)
151      return;
152
153   res_prop = resource_prop_from_uniform_prop(pname);
154
155   /* We need to first verify that each entry exists as active uniform. If
156    * not, generate error and do not cause any other side effects.
157    *
158    * In the case of and error condition, Page 16 (section 2.3.1 Errors)
159    * of the OpenGL 4.5 spec says:
160    *
161    *     "If the generating command modifies values through a pointer argu-
162    *     ment, no change is made to these values."
163    */
164   for (int i = 0; i < uniformCount; i++) {
165      if (!_mesa_program_resource_find_index(shProg, GL_UNIFORM,
166                                              uniformIndices[i])) {
167         _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)");
168         return;
169      }
170   }
171
172   for (int i = 0; i < uniformCount; i++) {
173      res = _mesa_program_resource_find_index(shProg, GL_UNIFORM,
174                                              uniformIndices[i]);
175      if (!_mesa_program_resource_prop(shProg, res, uniformIndices[i],
176                                       res_prop, &params[i],
177                                       false, "glGetActiveUniformsiv"))
178         break;
179   }
180}
181
182static struct gl_uniform_storage *
183validate_uniform_parameters(GLint location, GLsizei count,
184                            unsigned *array_index,
185                            struct gl_context *ctx,
186                            struct gl_shader_program *shProg,
187                            const char *caller)
188{
189   if (shProg == NULL) {
190      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", caller);
191      return NULL;
192   }
193
194   /* From page 12 (page 26 of the PDF) of the OpenGL 2.1 spec:
195    *
196    *     "If a negative number is provided where an argument of type sizei or
197    *     sizeiptr is specified, the error INVALID_VALUE is generated."
198    */
199   if (count < 0) {
200      _mesa_error(ctx, GL_INVALID_VALUE, "%s(count < 0)", caller);
201      return NULL;
202   }
203
204   /* Check that the given location is in bounds of uniform remap table.
205    * Unlinked programs will have NumUniformRemapTable == 0, so we can take
206    * the shProg->data->LinkStatus check out of the main path.
207    */
208   if (unlikely(location >= (GLint) shProg->NumUniformRemapTable)) {
209      if (!shProg->data->LinkStatus)
210         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)",
211                     caller);
212      else
213         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
214                     caller, location);
215
216      return NULL;
217   }
218
219   if (location == -1) {
220      if (!shProg->data->LinkStatus)
221         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)",
222                     caller);
223
224      return NULL;
225   }
226
227   /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
228    *
229    *     "If any of the following conditions occur, an INVALID_OPERATION
230    *     error is generated by the Uniform* commands, and no uniform values
231    *     are changed:
232    *
233    *     ...
234    *
235    *         - if no variable with a location of location exists in the
236    *           program object currently in use and location is not -1,
237    *         - if count is greater than one, and the uniform declared in the
238    *           shader is not an array variable,
239    */
240   if (location < -1 || !shProg->UniformRemapTable[location]) {
241      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
242                  caller, location);
243      return NULL;
244   }
245
246   /* If the driver storage pointer in remap table is -1, we ignore silently.
247    *
248    * GL_ARB_explicit_uniform_location spec says:
249    *     "What happens if Uniform* is called with an explicitly defined
250    *     uniform location, but that uniform is deemed inactive by the
251    *     linker?
252    *
253    *     RESOLVED: The call is ignored for inactive uniform variables and
254    *     no error is generated."
255    *
256    */
257   if (shProg->UniformRemapTable[location] ==
258       INACTIVE_UNIFORM_EXPLICIT_LOCATION)
259      return NULL;
260
261   struct gl_uniform_storage *const uni = shProg->UniformRemapTable[location];
262
263   /* Even though no location is assigned to a built-in uniform and this
264    * function should already have returned NULL, this test makes it explicit
265    * that we are not allowing to update the value of a built-in.
266    */
267   if (uni->builtin)
268      return NULL;
269
270   if (uni->array_elements == 0) {
271      if (count > 1) {
272         _mesa_error(ctx, GL_INVALID_OPERATION,
273                     "%s(count = %u for non-array \"%s\"@%d)",
274                     caller, count, uni->name, location);
275         return NULL;
276      }
277
278      assert((location - uni->remap_location) == 0);
279      *array_index = 0;
280   } else {
281      /* The array index specified by the uniform location is just the uniform
282       * location minus the base location of of the uniform.
283       */
284      *array_index = location - uni->remap_location;
285
286      /* If the uniform is an array, check that array_index is in bounds.
287       * array_index is unsigned so no need to check for less than zero.
288       */
289      if (*array_index >= uni->array_elements) {
290         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
291                     caller, location);
292         return NULL;
293      }
294   }
295   return uni;
296}
297
298/**
299 * Called via glGetUniform[fiui]v() to get the current value of a uniform.
300 */
301extern "C" void
302_mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
303		  GLsizei bufSize, enum glsl_base_type returnType,
304		  GLvoid *paramsOut)
305{
306   struct gl_shader_program *shProg =
307      _mesa_lookup_shader_program_err(ctx, program, "glGetUniformfv");
308   unsigned offset;
309
310   struct gl_uniform_storage *const uni =
311      validate_uniform_parameters(location, 1, &offset,
312                                  ctx, shProg, "glGetUniform");
313   if (uni == NULL) {
314      /* For glGetUniform, page 264 (page 278 of the PDF) of the OpenGL 2.1
315       * spec says:
316       *
317       *     "The error INVALID_OPERATION is generated if program has not been
318       *     linked successfully, or if location is not a valid location for
319       *     program."
320       *
321       * For glUniform, page 82 (page 96 of the PDF) of the OpenGL 2.1 spec
322       * says:
323       *
324       *     "If the value of location is -1, the Uniform* commands will
325       *     silently ignore the data passed in, and the current uniform
326       *     values will not be changed."
327       *
328       * Allowing -1 for the location parameter of glUniform allows
329       * applications to avoid error paths in the case that, for example, some
330       * uniform variable is removed by the compiler / linker after
331       * optimization.  In this case, the new value of the uniform is dropped
332       * on the floor.  For the case of glGetUniform, there is nothing
333       * sensible to do for a location of -1.
334       *
335       * If the location was -1, validate_unfirom_parameters will return NULL
336       * without raising an error.  Raise the error here.
337       */
338      if (location == -1) {
339         _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniform(location=%d)",
340                     location);
341      }
342
343      return;
344   }
345
346   {
347      unsigned elements = uni->type->components();
348      unsigned components = uni->type->vector_elements;
349
350      const int rmul = glsl_base_type_is_64bit(returnType) ? 2 : 1;
351      int dmul = (uni->type->is_64bit()) ? 2 : 1;
352
353      if ((uni->type->is_sampler() || uni->type->is_image()) &&
354          !uni->is_bindless) {
355         /* Non-bindless samplers/images are represented using unsigned integer
356          * 32-bit, while bindless handles are 64-bit.
357          */
358         dmul = 1;
359      }
360
361      /* Calculate the source base address *BEFORE* modifying elements to
362       * account for the size of the user's buffer.
363       */
364      const union gl_constant_value *src;
365      if (ctx->Const.PackedDriverUniformStorage &&
366          (uni->is_bindless || !uni->type->contains_opaque())) {
367         unsigned dword_elements = elements;
368
369         /* 16-bit uniforms are packed. */
370         if (glsl_base_type_is_16bit(uni->type->base_type)) {
371            dword_elements = DIV_ROUND_UP(components, 2) *
372                             uni->type->matrix_columns;
373         }
374
375         src = (gl_constant_value *) uni->driver_storage[0].data +
376            (offset * dword_elements * dmul);
377      } else {
378         src = &uni->storage[offset * elements * dmul];
379      }
380
381      assert(returnType == GLSL_TYPE_FLOAT || returnType == GLSL_TYPE_INT ||
382             returnType == GLSL_TYPE_UINT || returnType == GLSL_TYPE_DOUBLE ||
383             returnType == GLSL_TYPE_UINT64 || returnType == GLSL_TYPE_INT64);
384
385      /* doubles have a different size than the other 3 types */
386      unsigned bytes = sizeof(src[0]) * elements * rmul;
387      if (bufSize < 0 || bytes > (unsigned) bufSize) {
388         _mesa_error(ctx, GL_INVALID_OPERATION,
389                     "glGetnUniform*vARB(out of bounds: bufSize is %d,"
390                     " but %u bytes are required)", bufSize, bytes);
391         return;
392      }
393
394      /* If the return type and the uniform's native type are "compatible,"
395       * just memcpy the data.  If the types are not compatible, perform a
396       * slower convert-and-copy process.
397       */
398      if (returnType == uni->type->base_type ||
399          ((returnType == GLSL_TYPE_INT || returnType == GLSL_TYPE_UINT) &&
400           (uni->type->is_sampler() || uni->type->is_image())) ||
401          (returnType == GLSL_TYPE_UINT64 && uni->is_bindless)) {
402         memcpy(paramsOut, src, bytes);
403      } else {
404         union gl_constant_value *const dst =
405            (union gl_constant_value *) paramsOut;
406         /* This code could be optimized by putting the loop inside the switch
407          * statements.  However, this is not expected to be
408          * performance-critical code.
409          */
410         for (unsigned i = 0; i < elements; i++) {
411            int sidx = i * dmul;
412            int didx = i * rmul;
413
414            if (glsl_base_type_is_16bit(uni->type->base_type)) {
415               unsigned column = i / components;
416               unsigned row = i % components;
417               sidx = column * align(components, 2) + row;
418            }
419
420            switch (returnType) {
421            case GLSL_TYPE_FLOAT:
422               switch (uni->type->base_type) {
423               case GLSL_TYPE_FLOAT16:
424                  dst[didx].f = _mesa_half_to_float(((uint16_t*)src)[sidx]);
425                  break;
426               case GLSL_TYPE_UINT:
427                  dst[didx].f = (float) src[sidx].u;
428                  break;
429               case GLSL_TYPE_INT:
430               case GLSL_TYPE_SAMPLER:
431               case GLSL_TYPE_IMAGE:
432                  dst[didx].f = (float) src[sidx].i;
433                  break;
434               case GLSL_TYPE_BOOL:
435                  dst[didx].f = src[sidx].i ? 1.0f : 0.0f;
436                  break;
437               case GLSL_TYPE_DOUBLE: {
438                  double tmp;
439                  memcpy(&tmp, &src[sidx].f, sizeof(tmp));
440                  dst[didx].f = tmp;
441                  break;
442               }
443               case GLSL_TYPE_UINT64: {
444                  uint64_t tmp;
445                  memcpy(&tmp, &src[sidx].u, sizeof(tmp));
446                  dst[didx].f = tmp;
447                  break;
448                }
449               case GLSL_TYPE_INT64: {
450                  uint64_t tmp;
451                  memcpy(&tmp, &src[sidx].i, sizeof(tmp));
452                  dst[didx].f = tmp;
453                  break;
454               }
455               default:
456                  assert(!"Should not get here.");
457                  break;
458               }
459               break;
460
461            case GLSL_TYPE_DOUBLE:
462               switch (uni->type->base_type) {
463               case GLSL_TYPE_FLOAT16: {
464                  double f = _mesa_half_to_float(((uint16_t*)src)[sidx]);
465                  memcpy(&dst[didx].f, &f, sizeof(f));
466                  break;
467               }
468               case GLSL_TYPE_UINT: {
469                  double tmp = src[sidx].u;
470                  memcpy(&dst[didx].f, &tmp, sizeof(tmp));
471                  break;
472               }
473               case GLSL_TYPE_INT:
474               case GLSL_TYPE_SAMPLER:
475               case GLSL_TYPE_IMAGE: {
476                  double tmp = src[sidx].i;
477                  memcpy(&dst[didx].f, &tmp, sizeof(tmp));
478                  break;
479               }
480               case GLSL_TYPE_BOOL: {
481                  double tmp = src[sidx].i ? 1.0 : 0.0;
482                  memcpy(&dst[didx].f, &tmp, sizeof(tmp));
483                  break;
484               }
485               case GLSL_TYPE_FLOAT: {
486                  double tmp = src[sidx].f;
487                  memcpy(&dst[didx].f, &tmp, sizeof(tmp));
488                  break;
489               }
490               case GLSL_TYPE_UINT64: {
491                  uint64_t tmpu;
492                  double tmp;
493                  memcpy(&tmpu, &src[sidx].u, sizeof(tmpu));
494                  tmp = tmpu;
495                  memcpy(&dst[didx].f, &tmp, sizeof(tmp));
496                  break;
497               }
498               case GLSL_TYPE_INT64: {
499                  int64_t tmpi;
500                  double tmp;
501                  memcpy(&tmpi, &src[sidx].i, sizeof(tmpi));
502                  tmp = tmpi;
503                  memcpy(&dst[didx].f, &tmp, sizeof(tmp));
504                  break;
505               }
506               default:
507                  assert(!"Should not get here.");
508                  break;
509               }
510               break;
511
512            case GLSL_TYPE_INT:
513               switch (uni->type->base_type) {
514               case GLSL_TYPE_FLOAT:
515                  /* While the GL 3.2 core spec doesn't explicitly
516                   * state how conversion of float uniforms to integer
517                   * values works, in section 6.2 "State Tables" on
518                   * page 267 it says:
519                   *
520                   *     "Unless otherwise specified, when floating
521                   *      point state is returned as integer values or
522                   *      integer state is returned as floating-point
523                   *      values it is converted in the fashion
524                   *      described in section 6.1.2"
525                   *
526                   * That section, on page 248, says:
527                   *
528                   *     "If GetIntegerv or GetInteger64v are called,
529                   *      a floating-point value is rounded to the
530                   *      nearest integer..."
531                   */
532                  dst[didx].i = (int64_t) roundf(src[sidx].f);
533                  break;
534               case GLSL_TYPE_FLOAT16:
535                  dst[didx].i =
536                     (int64_t)roundf(_mesa_half_to_float(((uint16_t*)src)[sidx]));
537                  break;
538               case GLSL_TYPE_BOOL:
539                  dst[didx].i = src[sidx].i ? 1 : 0;
540                  break;
541               case GLSL_TYPE_UINT:
542                  dst[didx].i = MIN2(src[sidx].i, INT_MAX);
543                  break;
544               case GLSL_TYPE_DOUBLE: {
545                  double tmp;
546                  memcpy(&tmp, &src[sidx].f, sizeof(tmp));
547                  dst[didx].i = (int64_t) round(tmp);
548                  break;
549               }
550               case GLSL_TYPE_UINT64: {
551                  uint64_t tmp;
552                  memcpy(&tmp, &src[sidx].u, sizeof(tmp));
553                  dst[didx].i = tmp;
554                  break;
555               }
556               case GLSL_TYPE_INT64: {
557                  int64_t tmp;
558                  memcpy(&tmp, &src[sidx].i, sizeof(tmp));
559                  dst[didx].i = tmp;
560                  break;
561               }
562               default:
563                  assert(!"Should not get here.");
564                  break;
565               }
566               break;
567
568            case GLSL_TYPE_UINT:
569               switch (uni->type->base_type) {
570               case GLSL_TYPE_FLOAT:
571                  /* The spec isn't terribly clear how to handle negative
572                   * values with an unsigned return type.
573                   *
574                   * GL 4.5 section 2.2.2 ("Data Conversions for State
575                   * Query Commands") says:
576                   *
577                   * "If a value is so large in magnitude that it cannot be
578                   *  represented by the returned data type, then the nearest
579                   *  value representable using the requested type is
580                   *  returned."
581                   */
582                  dst[didx].u = src[sidx].f < 0.0f ?
583                     0u : (uint32_t) roundf(src[sidx].f);
584                  break;
585               case GLSL_TYPE_FLOAT16: {
586                  float f = _mesa_half_to_float(((uint16_t*)src)[sidx]);
587                  dst[didx].u = f < 0.0f ? 0u : (uint32_t)roundf(f);
588                  break;
589               }
590               case GLSL_TYPE_BOOL:
591                  dst[didx].i = src[sidx].i ? 1 : 0;
592                  break;
593               case GLSL_TYPE_INT:
594                  dst[didx].i = MAX2(src[sidx].i, 0);
595                  break;
596               case GLSL_TYPE_DOUBLE: {
597                  double tmp;
598                  memcpy(&tmp, &src[sidx].f, sizeof(tmp));
599                  dst[didx].u = tmp < 0.0 ? 0u : (uint32_t) round(tmp);
600                  break;
601               }
602               case GLSL_TYPE_UINT64: {
603                  uint64_t tmp;
604                  memcpy(&tmp, &src[sidx].u, sizeof(tmp));
605                  dst[didx].i = MIN2(tmp, INT_MAX);
606                  break;
607               }
608               case GLSL_TYPE_INT64: {
609                  int64_t tmp;
610                  memcpy(&tmp, &src[sidx].i, sizeof(tmp));
611                  dst[didx].i = MAX2(tmp, 0);
612                  break;
613               }
614               default:
615                  unreachable("invalid uniform type");
616               }
617               break;
618
619            case GLSL_TYPE_INT64:
620               switch (uni->type->base_type) {
621               case GLSL_TYPE_UINT: {
622                  uint64_t tmp = src[sidx].u;
623                  memcpy(&dst[didx].u, &tmp, sizeof(tmp));
624                  break;
625               }
626               case GLSL_TYPE_INT:
627               case GLSL_TYPE_SAMPLER:
628               case GLSL_TYPE_IMAGE: {
629                  int64_t tmp = src[sidx].i;
630                  memcpy(&dst[didx].u, &tmp, sizeof(tmp));
631                  break;
632               }
633               case GLSL_TYPE_BOOL: {
634                  int64_t tmp = src[sidx].i ? 1.0f : 0.0f;
635                  memcpy(&dst[didx].u, &tmp, sizeof(tmp));
636                  break;
637               }
638               case GLSL_TYPE_UINT64: {
639                  uint64_t u64;
640                  memcpy(&u64, &src[sidx].u, sizeof(u64));
641                  int64_t tmp = MIN2(u64, INT_MAX);
642                  memcpy(&dst[didx].u, &tmp, sizeof(tmp));
643                  break;
644               }
645               case GLSL_TYPE_FLOAT: {
646                  int64_t tmp = (int64_t) roundf(src[sidx].f);
647                  memcpy(&dst[didx].u, &tmp, sizeof(tmp));
648                  break;
649               }
650               case GLSL_TYPE_FLOAT16: {
651                  float f = _mesa_half_to_float(((uint16_t*)src)[sidx]);
652                  int64_t tmp = (int64_t) roundf(f);
653                  memcpy(&dst[didx].u, &tmp, sizeof(tmp));
654                  break;
655               }
656               case GLSL_TYPE_DOUBLE: {
657                  double d;
658                  memcpy(&d, &src[sidx].f, sizeof(d));
659                  int64_t tmp = (int64_t) round(d);
660                  memcpy(&dst[didx].u, &tmp, sizeof(tmp));
661                  break;
662               }
663               default:
664                  assert(!"Should not get here.");
665                  break;
666               }
667               break;
668
669            case GLSL_TYPE_UINT64:
670               switch (uni->type->base_type) {
671               case GLSL_TYPE_UINT: {
672                  uint64_t tmp = src[sidx].u;
673                  memcpy(&dst[didx].u, &tmp, sizeof(tmp));
674                  break;
675               }
676               case GLSL_TYPE_INT:
677               case GLSL_TYPE_SAMPLER:
678               case GLSL_TYPE_IMAGE: {
679                  int64_t tmp = MAX2(src[sidx].i, 0);
680                  memcpy(&dst[didx].u, &tmp, sizeof(tmp));
681                  break;
682               }
683               case GLSL_TYPE_BOOL: {
684                  int64_t tmp = src[sidx].i ? 1.0f : 0.0f;
685                  memcpy(&dst[didx].u, &tmp, sizeof(tmp));
686                  break;
687               }
688               case GLSL_TYPE_INT64: {
689                  uint64_t i64;
690                  memcpy(&i64, &src[sidx].i, sizeof(i64));
691                  uint64_t tmp = MAX2(i64, 0);
692                  memcpy(&dst[didx].u, &tmp, sizeof(tmp));
693                  break;
694               }
695               case GLSL_TYPE_FLOAT: {
696                  uint64_t tmp = src[sidx].f < 0.0f ?
697                     0ull : (uint64_t) roundf(src[sidx].f);
698                  memcpy(&dst[didx].u, &tmp, sizeof(tmp));
699                  break;
700               }
701               case GLSL_TYPE_FLOAT16: {
702                  float f = _mesa_half_to_float(((uint16_t*)src)[sidx]);
703                  uint64_t tmp = f < 0.0f ? 0ull : (uint64_t) roundf(f);
704                  memcpy(&dst[didx].u, &tmp, sizeof(tmp));
705                  break;
706               }
707               case GLSL_TYPE_DOUBLE: {
708                  double d;
709                  memcpy(&d, &src[sidx].f, sizeof(d));
710                  uint64_t tmp = (d < 0.0) ? 0ull : (uint64_t) round(d);
711                  memcpy(&dst[didx].u, &tmp, sizeof(tmp));
712                  break;
713               }
714               default:
715                  assert(!"Should not get here.");
716                  break;
717               }
718               break;
719
720            default:
721               assert(!"Should not get here.");
722               break;
723            }
724         }
725      }
726   }
727}
728
729static void
730log_uniform(const void *values, enum glsl_base_type basicType,
731	    unsigned rows, unsigned cols, unsigned count,
732	    bool transpose,
733	    const struct gl_shader_program *shProg,
734	    GLint location,
735	    const struct gl_uniform_storage *uni)
736{
737
738   const union gl_constant_value *v = (const union gl_constant_value *) values;
739   const unsigned elems = rows * cols * count;
740   const char *const extra = (cols == 1) ? "uniform" : "uniform matrix";
741
742   printf("Mesa: set program %u %s \"%s\" (loc %d, type \"%s\", "
743	  "transpose = %s) to: ",
744	  shProg->Name, extra, uni->name, location, uni->type->name,
745	  transpose ? "true" : "false");
746   for (unsigned i = 0; i < elems; i++) {
747      if (i != 0 && ((i % rows) == 0))
748	 printf(", ");
749
750      switch (basicType) {
751      case GLSL_TYPE_UINT:
752	 printf("%u ", v[i].u);
753	 break;
754      case GLSL_TYPE_INT:
755	 printf("%d ", v[i].i);
756	 break;
757      case GLSL_TYPE_UINT64: {
758         uint64_t tmp;
759         memcpy(&tmp, &v[i * 2].u, sizeof(tmp));
760         printf("%" PRIu64 " ", tmp);
761         break;
762      }
763      case GLSL_TYPE_INT64: {
764         int64_t tmp;
765         memcpy(&tmp, &v[i * 2].u, sizeof(tmp));
766         printf("%" PRId64 " ", tmp);
767         break;
768      }
769      case GLSL_TYPE_FLOAT:
770	 printf("%g ", v[i].f);
771	 break;
772      case GLSL_TYPE_DOUBLE: {
773         double tmp;
774         memcpy(&tmp, &v[i * 2].f, sizeof(tmp));
775         printf("%g ", tmp);
776         break;
777      }
778      default:
779	 assert(!"Should not get here.");
780	 break;
781      }
782   }
783   printf("\n");
784   fflush(stdout);
785}
786
787#if 0
788static void
789log_program_parameters(const struct gl_shader_program *shProg)
790{
791   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
792      if (shProg->_LinkedShaders[i] == NULL)
793	 continue;
794
795      const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program;
796
797      printf("Program %d %s shader parameters:\n",
798             shProg->Name, _mesa_shader_stage_to_string(i));
799      for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) {
800         unsigned pvo = prog->Parameters->ParameterValueOffset[j];
801         printf("%s: %u %p %f %f %f %f\n",
802		prog->Parameters->Parameters[j].Name,
803                pvo,
804                prog->Parameters->ParameterValues + pvo,
805                prog->Parameters->ParameterValues[pvo].f,
806                prog->Parameters->ParameterValues[pvo + 1].f,
807                prog->Parameters->ParameterValues[pvo + 2].f,
808                prog->Parameters->ParameterValues[pvo + 3].f);
809      }
810   }
811   fflush(stdout);
812}
813#endif
814
815/**
816 * Propagate some values from uniform backing storage to driver storage
817 *
818 * Values propagated from uniform backing storage to driver storage
819 * have all format / type conversions previously requested by the
820 * driver applied.  This function is most often called by the
821 * implementations of \c glUniform1f, etc. and \c glUniformMatrix2f,
822 * etc.
823 *
824 * \param uni          Uniform whose data is to be propagated to driver storage
825 * \param array_index  If \c uni is an array, this is the element of
826 *                     the array to be propagated.
827 * \param count        Number of array elements to propagate.
828 */
829extern "C" void
830_mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni,
831					   unsigned array_index,
832					   unsigned count)
833{
834   unsigned i;
835
836   const unsigned components = uni->type->vector_elements;
837   const unsigned vectors = uni->type->matrix_columns;
838   const int dmul = uni->type->is_64bit() ? 2 : 1;
839
840   /* Store the data in the driver's requested type in the driver's storage
841    * areas.
842    */
843   unsigned src_vector_byte_stride = components * 4 * dmul;
844
845   for (i = 0; i < uni->num_driver_storage; i++) {
846      struct gl_uniform_driver_storage *const store = &uni->driver_storage[i];
847      uint8_t *dst = (uint8_t *) store->data;
848      const unsigned extra_stride =
849	 store->element_stride - (vectors * store->vector_stride);
850      const uint8_t *src =
851	 (uint8_t *) (&uni->storage[array_index * (dmul * components * vectors)].i);
852
853#if 0
854      printf("%s: %p[%d] components=%u vectors=%u count=%u vector_stride=%u "
855	     "extra_stride=%u\n",
856	     __func__, dst, array_index, components,
857	     vectors, count, store->vector_stride, extra_stride);
858#endif
859
860      dst += array_index * store->element_stride;
861
862      switch (store->format) {
863      case uniform_native: {
864	 unsigned j;
865	 unsigned v;
866
867	 if (src_vector_byte_stride == store->vector_stride) {
868	    if (extra_stride) {
869	       for (j = 0; j < count; j++) {
870	          memcpy(dst, src, src_vector_byte_stride * vectors);
871	          src += src_vector_byte_stride * vectors;
872	          dst += store->vector_stride * vectors;
873
874	          dst += extra_stride;
875	       }
876	    } else {
877	       /* Unigine Heaven benchmark gets here */
878	       memcpy(dst, src, src_vector_byte_stride * vectors * count);
879	       src += src_vector_byte_stride * vectors * count;
880	       dst += store->vector_stride * vectors * count;
881	    }
882	 } else {
883	    for (j = 0; j < count; j++) {
884	       for (v = 0; v < vectors; v++) {
885	          memcpy(dst, src, src_vector_byte_stride);
886	          src += src_vector_byte_stride;
887	          dst += store->vector_stride;
888	       }
889
890	       dst += extra_stride;
891	    }
892	 }
893	 break;
894      }
895
896      case uniform_int_float: {
897	 const int *isrc = (const int *) src;
898	 unsigned j;
899	 unsigned v;
900	 unsigned c;
901
902	 for (j = 0; j < count; j++) {
903	    for (v = 0; v < vectors; v++) {
904	       for (c = 0; c < components; c++) {
905		  ((float *) dst)[c] = (float) *isrc;
906		  isrc++;
907	       }
908
909	       dst += store->vector_stride;
910	    }
911
912	    dst += extra_stride;
913	 }
914	 break;
915      }
916
917      default:
918	 assert(!"Should not get here.");
919	 break;
920      }
921   }
922}
923
924
925/**
926 * Return printable string for a given GLSL_TYPE_x
927 */
928static const char *
929glsl_type_name(enum glsl_base_type type)
930{
931   switch (type) {
932   case GLSL_TYPE_UINT:
933      return "uint";
934   case GLSL_TYPE_INT:
935      return "int";
936   case GLSL_TYPE_FLOAT:
937      return "float";
938   case GLSL_TYPE_DOUBLE:
939      return "double";
940   case GLSL_TYPE_UINT64:
941      return "uint64";
942   case GLSL_TYPE_INT64:
943      return "int64";
944   case GLSL_TYPE_BOOL:
945      return "bool";
946   case GLSL_TYPE_SAMPLER:
947      return "sampler";
948   case GLSL_TYPE_IMAGE:
949      return "image";
950   case GLSL_TYPE_ATOMIC_UINT:
951      return "atomic_uint";
952   case GLSL_TYPE_STRUCT:
953      return "struct";
954   case GLSL_TYPE_INTERFACE:
955      return "interface";
956   case GLSL_TYPE_ARRAY:
957      return "array";
958   case GLSL_TYPE_VOID:
959      return "void";
960   case GLSL_TYPE_ERROR:
961      return "error";
962   default:
963      return "other";
964   }
965}
966
967
968static struct gl_uniform_storage *
969validate_uniform(GLint location, GLsizei count, const GLvoid *values,
970                 unsigned *offset, struct gl_context *ctx,
971                 struct gl_shader_program *shProg,
972                 enum glsl_base_type basicType, unsigned src_components)
973{
974   struct gl_uniform_storage *const uni =
975      validate_uniform_parameters(location, count, offset,
976                                  ctx, shProg, "glUniform");
977   if (uni == NULL)
978      return NULL;
979
980   if (uni->type->is_matrix()) {
981      /* Can't set matrix uniforms (like mat4) with glUniform */
982      _mesa_error(ctx, GL_INVALID_OPERATION,
983                  "glUniform%u(uniform \"%s\"@%d is matrix)",
984                  src_components, uni->name, location);
985      return NULL;
986   }
987
988   /* Verify that the types are compatible. */
989   const unsigned components = uni->type->vector_elements;
990
991   if (components != src_components) {
992      /* glUniformN() must match float/vecN type */
993      _mesa_error(ctx, GL_INVALID_OPERATION,
994                  "glUniform%u(\"%s\"@%u has %u components, not %u)",
995                  src_components, uni->name, location,
996                  components, src_components);
997      return NULL;
998   }
999
1000   bool match;
1001   switch (uni->type->base_type) {
1002   case GLSL_TYPE_BOOL:
1003      match = (basicType != GLSL_TYPE_DOUBLE);
1004      break;
1005   case GLSL_TYPE_SAMPLER:
1006      match = (basicType == GLSL_TYPE_INT);
1007      break;
1008   case GLSL_TYPE_IMAGE:
1009      match = (basicType == GLSL_TYPE_INT && _mesa_is_desktop_gl(ctx));
1010      break;
1011   case GLSL_TYPE_FLOAT16:
1012      match = basicType == GLSL_TYPE_FLOAT;
1013      break;
1014   default:
1015      match = (basicType == uni->type->base_type);
1016      break;
1017   }
1018
1019   if (!match) {
1020      _mesa_error(ctx, GL_INVALID_OPERATION,
1021                  "glUniform%u(\"%s\"@%d is %s, not %s)",
1022                  src_components, uni->name, location,
1023                  glsl_type_name(uni->type->base_type),
1024                  glsl_type_name(basicType));
1025      return NULL;
1026   }
1027
1028   if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
1029      log_uniform(values, basicType, components, 1, count,
1030                  false, shProg, location, uni);
1031   }
1032
1033   /* Page 100 (page 116 of the PDF) of the OpenGL 3.0 spec says:
1034    *
1035    *     "Setting a sampler's value to i selects texture image unit number
1036    *     i. The values of i range from zero to the implementation- dependent
1037    *     maximum supported number of texture image units."
1038    *
1039    * In addition, table 2.3, "Summary of GL errors," on page 17 (page 33 of
1040    * the PDF) says:
1041    *
1042    *     "Error         Description                    Offending command
1043    *                                                   ignored?
1044    *     ...
1045    *     INVALID_VALUE  Numeric argument out of range  Yes"
1046    *
1047    * Based on that, when an invalid sampler is specified, we generate a
1048    * GL_INVALID_VALUE error and ignore the command.
1049    */
1050   if (uni->type->is_sampler()) {
1051      for (int i = 0; i < count; i++) {
1052         const unsigned texUnit = ((unsigned *) values)[i];
1053
1054         /* check that the sampler (tex unit index) is legal */
1055         if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
1056            _mesa_error(ctx, GL_INVALID_VALUE,
1057                        "glUniform1i(invalid sampler/tex unit index for "
1058                        "uniform %d)", location);
1059            return NULL;
1060         }
1061      }
1062      /* We need to reset the validate flag on changes to samplers in case
1063       * two different sampler types are set to the same texture unit.
1064       */
1065      ctx->_Shader->Validated = ctx->_Shader->UserValidated = GL_FALSE;
1066   }
1067
1068   if (uni->type->is_image()) {
1069      for (int i = 0; i < count; i++) {
1070         const int unit = ((GLint *) values)[i];
1071
1072         /* check that the image unit is legal */
1073         if (unit < 0 || unit >= (int)ctx->Const.MaxImageUnits) {
1074            _mesa_error(ctx, GL_INVALID_VALUE,
1075                        "glUniform1i(invalid image unit index for uniform %d)",
1076                        location);
1077            return NULL;
1078         }
1079      }
1080   }
1081
1082   return uni;
1083}
1084
1085void
1086_mesa_flush_vertices_for_uniforms(struct gl_context *ctx,
1087                                  const struct gl_uniform_storage *uni)
1088{
1089   /* Opaque uniforms have no storage unless they are bindless */
1090   if (!uni->is_bindless && uni->type->contains_opaque()) {
1091      /* Samplers flush on demand and ignore redundant updates. */
1092      if (!uni->type->is_sampler())
1093         FLUSH_VERTICES(ctx, 0, 0);
1094      return;
1095   }
1096
1097   uint64_t new_driver_state = 0;
1098   unsigned mask = uni->active_shader_mask;
1099
1100   while (mask) {
1101      unsigned index = u_bit_scan(&mask);
1102
1103      assert(index < MESA_SHADER_STAGES);
1104      new_driver_state |= ctx->DriverFlags.NewShaderConstants[index];
1105   }
1106
1107   FLUSH_VERTICES(ctx, new_driver_state ? 0 : _NEW_PROGRAM_CONSTANTS, 0);
1108   ctx->NewDriverState |= new_driver_state;
1109}
1110
1111static bool
1112copy_uniforms_to_storage(gl_constant_value *storage,
1113                         struct gl_uniform_storage *uni,
1114                         struct gl_context *ctx, GLsizei count,
1115                         const GLvoid *values, const int size_mul,
1116                         const unsigned offset, const unsigned components,
1117                         enum glsl_base_type basicType, bool flush)
1118{
1119   const gl_constant_value *src = (const gl_constant_value*)values;
1120   bool copy_as_uint64 = uni->is_bindless &&
1121                         (uni->type->is_sampler() || uni->type->is_image());
1122   bool copy_to_float16 = uni->type->base_type == GLSL_TYPE_FLOAT16;
1123
1124   if (!uni->type->is_boolean() && !copy_as_uint64 && !copy_to_float16) {
1125      unsigned size = sizeof(storage[0]) * components * count * size_mul;
1126
1127      if (!memcmp(storage, values, size))
1128         return false;
1129
1130      if (flush)
1131         _mesa_flush_vertices_for_uniforms(ctx, uni);
1132
1133      memcpy(storage, values, size);
1134      return true;
1135   } else if (copy_to_float16) {
1136      assert(ctx->Const.PackedDriverUniformStorage);
1137      const unsigned dst_components = align(components, 2);
1138      uint16_t *dst = (uint16_t*)storage;
1139
1140      int i = 0;
1141      unsigned c = 0;
1142
1143      if (flush) {
1144         /* Find the first element that's different. */
1145         for (; i < count; i++) {
1146            for (; c < components; c++) {
1147               if (dst[c] != _mesa_float_to_half(src[c].f)) {
1148                  _mesa_flush_vertices_for_uniforms(ctx, uni);
1149                  flush = false;
1150                  goto break_loops;
1151               }
1152            }
1153            c = 0;
1154            dst += dst_components;
1155            src += components;
1156         }
1157      break_loops:
1158         if (flush)
1159            return false; /* No change. */
1160      }
1161
1162      /* Set the remaining elements. We know that at least 1 element is
1163       * different and that we have flushed.
1164       */
1165      for (; i < count; i++) {
1166         for (; c < components; c++)
1167            dst[c] = _mesa_float_to_half(src[c].f);
1168
1169         c = 0;
1170         dst += dst_components;
1171         src += components;
1172      }
1173
1174      return true;
1175   } else if (copy_as_uint64) {
1176      const unsigned elems = components * count;
1177      uint64_t *dst = (uint64_t*)storage;
1178      unsigned i = 0;
1179
1180      if (flush) {
1181         /* Find the first element that's different. */
1182         for (; i < elems; i++) {
1183            if (dst[i] != src[i].u) {
1184               _mesa_flush_vertices_for_uniforms(ctx, uni);
1185               flush = false;
1186               break;
1187            }
1188         }
1189         if (flush)
1190            return false; /* No change. */
1191      }
1192
1193      /* Set the remaining elements. We know that at least 1 element is
1194       * different and that we have flushed.
1195       */
1196      for (; i < elems; i++)
1197         dst[i] = src[i].u;
1198
1199      return true;
1200   } else {
1201      const unsigned elems = components * count;
1202      gl_constant_value *dst = storage;
1203
1204      if (basicType == GLSL_TYPE_FLOAT) {
1205         unsigned i = 0;
1206
1207         if (flush) {
1208            /* Find the first element that's different. */
1209            for (; i < elems; i++) {
1210               if (dst[i].u !=
1211                   (src[i].f != 0.0f ? ctx->Const.UniformBooleanTrue : 0)) {
1212                  _mesa_flush_vertices_for_uniforms(ctx, uni);
1213                  flush = false;
1214                  break;
1215               }
1216            }
1217            if (flush)
1218               return false; /* No change. */
1219         }
1220
1221         /* Set the remaining elements. We know that at least 1 element is
1222          * different and that we have flushed.
1223          */
1224         for (; i < elems; i++)
1225            dst[i].u = src[i].f != 0.0f ? ctx->Const.UniformBooleanTrue : 0;
1226
1227         return true;
1228      } else {
1229         unsigned i = 0;
1230
1231         if (flush) {
1232            /* Find the first element that's different. */
1233            for (; i < elems; i++) {
1234               if (dst[i].u !=
1235                   (src[i].u ? ctx->Const.UniformBooleanTrue : 0)) {
1236                  _mesa_flush_vertices_for_uniforms(ctx, uni);
1237                  flush = false;
1238                  break;
1239               }
1240            }
1241            if (flush)
1242               return false; /* No change. */
1243         }
1244
1245         /* Set the remaining elements. We know that at least 1 element is
1246          * different and that we have flushed.
1247          */
1248         for (; i < elems; i++)
1249            dst[i].u = src[i].u ? ctx->Const.UniformBooleanTrue : 0;
1250
1251         return true;
1252      }
1253   }
1254}
1255
1256
1257/**
1258 * Called via glUniform*() functions.
1259 */
1260extern "C" void
1261_mesa_uniform(GLint location, GLsizei count, const GLvoid *values,
1262              struct gl_context *ctx, struct gl_shader_program *shProg,
1263              enum glsl_base_type basicType, unsigned src_components)
1264{
1265   unsigned offset;
1266   int size_mul = glsl_base_type_is_64bit(basicType) ? 2 : 1;
1267
1268   struct gl_uniform_storage *uni;
1269   if (_mesa_is_no_error_enabled(ctx)) {
1270      /* From Seciton 7.6 (UNIFORM VARIABLES) of the OpenGL 4.5 spec:
1271       *
1272       *   "If the value of location is -1, the Uniform* commands will
1273       *   silently ignore the data passed in, and the current uniform values
1274       *   will not be changed.
1275       */
1276      if (location == -1)
1277         return;
1278
1279      if (location >= (int)shProg->NumUniformRemapTable)
1280         return;
1281
1282      uni = shProg->UniformRemapTable[location];
1283      if (!uni || uni == INACTIVE_UNIFORM_EXPLICIT_LOCATION)
1284         return;
1285
1286      /* The array index specified by the uniform location is just the
1287       * uniform location minus the base location of of the uniform.
1288       */
1289      assert(uni->array_elements > 0 || location == (int)uni->remap_location);
1290      offset = location - uni->remap_location;
1291   } else {
1292      uni = validate_uniform(location, count, values, &offset, ctx, shProg,
1293                             basicType, src_components);
1294      if (!uni)
1295         return;
1296   }
1297
1298   const unsigned components = uni->type->vector_elements;
1299
1300   /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
1301    *
1302    *     "When loading N elements starting at an arbitrary position k in a
1303    *     uniform declared as an array, elements k through k + N - 1 in the
1304    *     array will be replaced with the new values. Values for any array
1305    *     element that exceeds the highest array element index used, as
1306    *     reported by GetActiveUniform, will be ignored by the GL."
1307    *
1308    * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
1309    * will have already generated an error.
1310    */
1311   if (uni->array_elements != 0) {
1312      count = MIN2(count, (int) (uni->array_elements - offset));
1313   }
1314
1315   /* Store the data in the "actual type" backing storage for the uniform.
1316    */
1317   bool ctx_flushed = false;
1318   gl_constant_value *storage;
1319   if (ctx->Const.PackedDriverUniformStorage &&
1320       (uni->is_bindless || !uni->type->contains_opaque())) {
1321      for (unsigned s = 0; s < uni->num_driver_storage; s++) {
1322         unsigned dword_components = components;
1323
1324         /* 16-bit uniforms are packed. */
1325         if (glsl_base_type_is_16bit(uni->type->base_type))
1326            dword_components = DIV_ROUND_UP(dword_components, 2);
1327
1328         storage = (gl_constant_value *)
1329            uni->driver_storage[s].data + (size_mul * offset * dword_components);
1330
1331         if (copy_uniforms_to_storage(storage, uni, ctx, count, values, size_mul,
1332                                      offset, components, basicType, !ctx_flushed))
1333            ctx_flushed = true;
1334      }
1335   } else {
1336      storage = &uni->storage[size_mul * components * offset];
1337      if (copy_uniforms_to_storage(storage, uni, ctx, count, values, size_mul,
1338                                   offset, components, basicType, !ctx_flushed)) {
1339         _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
1340         ctx_flushed = true;
1341      }
1342   }
1343   /* Return early if possible. Bindless samplers need to be processed
1344    * because of the !sampler->bound codepath below.
1345    */
1346   if (!ctx_flushed && !(uni->type->is_sampler() && uni->is_bindless))
1347      return; /* no change in uniform values */
1348
1349   /* If the uniform is a sampler, do the extra magic necessary to propagate
1350    * the changes through.
1351    */
1352   if (uni->type->is_sampler()) {
1353      /* Note that samplers are the only uniforms that don't call
1354       * FLUSH_VERTICES above.
1355       */
1356      bool flushed = false;
1357      bool any_changed = false;
1358
1359      shProg->SamplersValidated = GL_TRUE;
1360
1361      for (int i = 0; i < MESA_SHADER_STAGES; i++) {
1362         struct gl_linked_shader *const sh = shProg->_LinkedShaders[i];
1363
1364         /* If the shader stage doesn't use the sampler uniform, skip this. */
1365         if (!uni->opaque[i].active)
1366            continue;
1367
1368         bool changed = false;
1369         for (int j = 0; j < count; j++) {
1370            unsigned unit = uni->opaque[i].index + offset + j;
1371            unsigned value = ((unsigned *)values)[j];
1372
1373            if (uni->is_bindless) {
1374               struct gl_bindless_sampler *sampler =
1375                  &sh->Program->sh.BindlessSamplers[unit];
1376
1377               /* Mark this bindless sampler as bound to a texture unit.
1378                */
1379               if (sampler->unit != value || !sampler->bound) {
1380                  if (!flushed) {
1381                     FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT | _NEW_PROGRAM, 0);
1382                     flushed = true;
1383                  }
1384                  sampler->unit = value;
1385                  changed = true;
1386               }
1387               sampler->bound = true;
1388               sh->Program->sh.HasBoundBindlessSampler = true;
1389            } else {
1390               if (sh->Program->SamplerUnits[unit] != value) {
1391                  if (!flushed) {
1392                     FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT | _NEW_PROGRAM, 0);
1393                     flushed = true;
1394                  }
1395                  sh->Program->SamplerUnits[unit] = value;
1396                  changed = true;
1397               }
1398            }
1399         }
1400
1401         if (changed) {
1402            struct gl_program *const prog = sh->Program;
1403            _mesa_update_shader_textures_used(shProg, prog);
1404            if (ctx->Driver.SamplerUniformChange)
1405               ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog);
1406            any_changed = true;
1407         }
1408      }
1409
1410      if (any_changed)
1411         _mesa_update_valid_to_render_state(ctx);
1412   }
1413
1414   /* If the uniform is an image, update the mapping from image
1415    * uniforms to image units present in the shader data structure.
1416    */
1417   if (uni->type->is_image()) {
1418      for (int i = 0; i < MESA_SHADER_STAGES; i++) {
1419         struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
1420
1421         /* If the shader stage doesn't use the image uniform, skip this. */
1422         if (!uni->opaque[i].active)
1423            continue;
1424
1425         for (int j = 0; j < count; j++) {
1426            unsigned unit = uni->opaque[i].index + offset + j;
1427            unsigned value = ((unsigned *)values)[j];
1428
1429            if (uni->is_bindless) {
1430               struct gl_bindless_image *image =
1431                  &sh->Program->sh.BindlessImages[unit];
1432
1433               /* Mark this bindless image as bound to an image unit.
1434                */
1435               image->unit = value;
1436               image->bound = true;
1437               sh->Program->sh.HasBoundBindlessImage = true;
1438            } else {
1439               sh->Program->sh.ImageUnits[unit] = value;
1440            }
1441         }
1442      }
1443
1444      ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;
1445   }
1446}
1447
1448
1449static bool
1450copy_uniform_matrix_to_storage(struct gl_context *ctx,
1451                               gl_constant_value *storage,
1452                               struct gl_uniform_storage *const uni,
1453                               unsigned count, const void *values,
1454                               const unsigned size_mul, const unsigned offset,
1455                               const unsigned components,
1456                               const unsigned vectors, bool transpose,
1457                               unsigned cols, unsigned rows,
1458                               enum glsl_base_type basicType, bool flush)
1459{
1460   const unsigned elements = components * vectors;
1461   const unsigned size = sizeof(storage[0]) * elements * count * size_mul;
1462
1463   if (uni->type->base_type == GLSL_TYPE_FLOAT16) {
1464      assert(ctx->Const.PackedDriverUniformStorage);
1465      const unsigned dst_components = align(components, 2);
1466      const unsigned dst_elements = dst_components * vectors;
1467
1468      if (!transpose) {
1469         const float *src = (const float *)values;
1470         uint16_t *dst = (uint16_t*)storage;
1471
1472         unsigned i = 0, r = 0, c = 0;
1473
1474         if (flush) {
1475            /* Find the first element that's different. */
1476            for (; i < count; i++) {
1477               for (; c < cols; c++) {
1478                  for (; r < rows; r++) {
1479                     if (dst[(c * dst_components) + r] !=
1480                         _mesa_float_to_half(src[(c * components) + r])) {
1481                        _mesa_flush_vertices_for_uniforms(ctx, uni);
1482                        flush = false;
1483                        goto break_loops_16bit;
1484                     }
1485                  }
1486                  r = 0;
1487               }
1488               c = 0;
1489               dst += dst_elements;
1490               src += elements;
1491            }
1492
1493         break_loops_16bit:
1494            if (flush)
1495               return false; /* No change. */
1496         }
1497
1498         /* Set the remaining elements. We know that at least 1 element is
1499          * different and that we have flushed.
1500          */
1501         for (; i < count; i++) {
1502            for (; c < cols; c++) {
1503               for (; r < rows; r++) {
1504                  dst[(c * dst_components) + r] =
1505                     _mesa_float_to_half(src[(c * components) + r]);
1506               }
1507               r = 0;
1508            }
1509            c = 0;
1510            dst += dst_elements;
1511            src += elements;
1512         }
1513         return true;
1514      } else {
1515         /* Transpose the matrix. */
1516         const float *src = (const float *)values;
1517         uint16_t *dst = (uint16_t*)storage;
1518
1519         unsigned i = 0, r = 0, c = 0;
1520
1521         if (flush) {
1522            /* Find the first element that's different. */
1523            for (; i < count; i++) {
1524               for (; r < rows; r++) {
1525                  for (; c < cols; c++) {
1526                     if (dst[(c * dst_components) + r] !=
1527                         _mesa_float_to_half(src[c + (r * vectors)])) {
1528                        _mesa_flush_vertices_for_uniforms(ctx, uni);
1529                        flush = false;
1530                        goto break_loops_16bit_transpose;
1531                     }
1532                  }
1533                  c = 0;
1534               }
1535               r = 0;
1536               dst += elements;
1537               src += elements;
1538            }
1539
1540         break_loops_16bit_transpose:
1541            if (flush)
1542               return false; /* No change. */
1543         }
1544
1545         /* Set the remaining elements. We know that at least 1 element is
1546          * different and that we have flushed.
1547          */
1548         for (; i < count; i++) {
1549            for (; r < rows; r++) {
1550               for (; c < cols; c++) {
1551                  dst[(c * dst_components) + r] =
1552                     _mesa_float_to_half(src[c + (r * vectors)]);
1553               }
1554               c = 0;
1555            }
1556            r = 0;
1557            dst += elements;
1558            src += elements;
1559         }
1560         return true;
1561      }
1562   } else if (!transpose) {
1563      if (!memcmp(storage, values, size))
1564         return false;
1565
1566      if (flush)
1567         _mesa_flush_vertices_for_uniforms(ctx, uni);
1568
1569      memcpy(storage, values, size);
1570      return true;
1571   } else if (basicType == GLSL_TYPE_FLOAT) {
1572      /* Transpose the matrix. */
1573      const float *src = (const float *)values;
1574      float *dst = (float*)storage;
1575
1576      unsigned i = 0, r = 0, c = 0;
1577
1578      if (flush) {
1579         /* Find the first element that's different. */
1580         for (; i < count; i++) {
1581            for (; r < rows; r++) {
1582               for (; c < cols; c++) {
1583                  if (dst[(c * components) + r] != src[c + (r * vectors)]) {
1584                     _mesa_flush_vertices_for_uniforms(ctx, uni);
1585                     flush = false;
1586                     goto break_loops;
1587                  }
1588               }
1589               c = 0;
1590            }
1591            r = 0;
1592            dst += elements;
1593            src += elements;
1594         }
1595
1596      break_loops:
1597         if (flush)
1598            return false; /* No change. */
1599      }
1600
1601      /* Set the remaining elements. We know that at least 1 element is
1602       * different and that we have flushed.
1603       */
1604      for (; i < count; i++) {
1605         for (; r < rows; r++) {
1606            for (; c < cols; c++)
1607               dst[(c * components) + r] = src[c + (r * vectors)];
1608            c = 0;
1609         }
1610         r = 0;
1611         dst += elements;
1612         src += elements;
1613      }
1614      return true;
1615   } else {
1616      assert(basicType == GLSL_TYPE_DOUBLE);
1617      const double *src = (const double *)values;
1618      double *dst = (double*)storage;
1619
1620      unsigned i = 0, r = 0, c = 0;
1621
1622      if (flush) {
1623         /* Find the first element that's different. */
1624         for (; i < count; i++) {
1625            for (; r < rows; r++) {
1626               for (; c < cols; c++) {
1627                  if (dst[(c * components) + r] != src[c + (r * vectors)]) {
1628                     _mesa_flush_vertices_for_uniforms(ctx, uni);
1629                     flush = false;
1630                     goto break_loops2;
1631                  }
1632               }
1633               c = 0;
1634            }
1635            r = 0;
1636            dst += elements;
1637            src += elements;
1638         }
1639
1640      break_loops2:
1641         if (flush)
1642            return false; /* No change. */
1643      }
1644
1645      /* Set the remaining elements. We know that at least 1 element is
1646       * different and that we have flushed.
1647       */
1648      for (; i < count; i++) {
1649         for (; r < rows; r++) {
1650            for (; c < cols; c++)
1651               dst[(c * components) + r] = src[c + (r * vectors)];
1652            c = 0;
1653         }
1654         r = 0;
1655         dst += elements;
1656         src += elements;
1657      }
1658      return true;
1659   }
1660}
1661
1662
1663/**
1664 * Called by glUniformMatrix*() functions.
1665 * Note: cols=2, rows=4  ==>  array[2] of vec4
1666 */
1667extern "C" void
1668_mesa_uniform_matrix(GLint location, GLsizei count,
1669                     GLboolean transpose, const void *values,
1670                     struct gl_context *ctx, struct gl_shader_program *shProg,
1671                     GLuint cols, GLuint rows, enum glsl_base_type basicType)
1672{
1673   unsigned offset;
1674   struct gl_uniform_storage *const uni =
1675      validate_uniform_parameters(location, count, &offset,
1676                                  ctx, shProg, "glUniformMatrix");
1677   if (uni == NULL)
1678      return;
1679
1680   /* GL_INVALID_VALUE is generated if `transpose' is not GL_FALSE.
1681    * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml
1682    */
1683   if (transpose) {
1684      if (ctx->API == API_OPENGLES2 && ctx->Version < 30) {
1685         _mesa_error(ctx, GL_INVALID_VALUE,
1686                     "glUniformMatrix(matrix transpose is not GL_FALSE)");
1687         return;
1688      }
1689   }
1690
1691   if (!uni->type->is_matrix()) {
1692      _mesa_error(ctx, GL_INVALID_OPERATION,
1693		  "glUniformMatrix(non-matrix uniform)");
1694      return;
1695   }
1696
1697   assert(basicType == GLSL_TYPE_FLOAT || basicType == GLSL_TYPE_DOUBLE);
1698   const unsigned size_mul = basicType == GLSL_TYPE_DOUBLE ? 2 : 1;
1699
1700   assert(!uni->type->is_sampler());
1701   const unsigned vectors = uni->type->matrix_columns;
1702   const unsigned components = uni->type->vector_elements;
1703
1704   /* Verify that the types are compatible.  This is greatly simplified for
1705    * matrices because they can only have a float base type.
1706    */
1707   if (vectors != cols || components != rows) {
1708      _mesa_error(ctx, GL_INVALID_OPERATION,
1709		  "glUniformMatrix(matrix size mismatch)");
1710      return;
1711   }
1712
1713   /* Section 2.11.7 (Uniform Variables) of the OpenGL 4.2 Core Profile spec
1714    * says:
1715    *
1716    *     "If any of the following conditions occur, an INVALID_OPERATION
1717    *     error is generated by the Uniform* commands, and no uniform values
1718    *     are changed:
1719    *
1720    *     ...
1721    *
1722    *     - if the uniform declared in the shader is not of type boolean and
1723    *       the type indicated in the name of the Uniform* command used does
1724    *       not match the type of the uniform"
1725    *
1726    * There are no Boolean matrix types, so we do not need to allow
1727    * GLSL_TYPE_BOOL here (as _mesa_uniform does).
1728    */
1729   if (uni->type->base_type != basicType &&
1730       !(uni->type->base_type == GLSL_TYPE_FLOAT16 &&
1731         basicType == GLSL_TYPE_FLOAT)) {
1732      _mesa_error(ctx, GL_INVALID_OPERATION,
1733                  "glUniformMatrix%ux%u(\"%s\"@%d is %s, not %s)",
1734                  cols, rows, uni->name, location,
1735                  glsl_type_name(uni->type->base_type),
1736                  glsl_type_name(basicType));
1737      return;
1738   }
1739
1740   if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
1741      log_uniform(values, uni->type->base_type, components, vectors, count,
1742		  bool(transpose), shProg, location, uni);
1743   }
1744
1745   /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
1746    *
1747    *     "When loading N elements starting at an arbitrary position k in a
1748    *     uniform declared as an array, elements k through k + N - 1 in the
1749    *     array will be replaced with the new values. Values for any array
1750    *     element that exceeds the highest array element index used, as
1751    *     reported by GetActiveUniform, will be ignored by the GL."
1752    *
1753    * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
1754    * will have already generated an error.
1755    */
1756   if (uni->array_elements != 0) {
1757      count = MIN2(count, (int) (uni->array_elements - offset));
1758   }
1759
1760   /* Store the data in the "actual type" backing storage for the uniform.
1761    */
1762   gl_constant_value *storage;
1763   const unsigned elements = components * vectors;
1764   if (ctx->Const.PackedDriverUniformStorage) {
1765      bool flushed = false;
1766
1767      for (unsigned s = 0; s < uni->num_driver_storage; s++) {
1768         unsigned dword_components = components;
1769
1770         /* 16-bit uniforms are packed. */
1771         if (glsl_base_type_is_16bit(uni->type->base_type))
1772            dword_components = DIV_ROUND_UP(dword_components, 2);
1773
1774         storage = (gl_constant_value *)
1775            uni->driver_storage[s].data +
1776            (size_mul * offset * dword_components * vectors);
1777
1778         if (copy_uniform_matrix_to_storage(ctx, storage, uni, count, values,
1779                                            size_mul, offset, components,
1780                                            vectors, transpose, cols, rows,
1781                                            basicType, !flushed))
1782            flushed = true;
1783      }
1784   } else {
1785      storage =  &uni->storage[size_mul * elements * offset];
1786      if (copy_uniform_matrix_to_storage(ctx, storage, uni, count, values,
1787                                         size_mul, offset, components, vectors,
1788                                         transpose, cols, rows, basicType,
1789                                         true))
1790         _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
1791   }
1792}
1793
1794static void
1795update_bound_bindless_sampler_flag(struct gl_program *prog)
1796{
1797   unsigned i;
1798
1799   if (likely(!prog->sh.HasBoundBindlessSampler))
1800      return;
1801
1802   for (i = 0; i < prog->sh.NumBindlessSamplers; i++) {
1803      struct gl_bindless_sampler *sampler = &prog->sh.BindlessSamplers[i];
1804
1805      if (sampler->bound)
1806         return;
1807   }
1808   prog->sh.HasBoundBindlessSampler = false;
1809}
1810
1811static void
1812update_bound_bindless_image_flag(struct gl_program *prog)
1813{
1814   unsigned i;
1815
1816   if (likely(!prog->sh.HasBoundBindlessImage))
1817      return;
1818
1819   for (i = 0; i < prog->sh.NumBindlessImages; i++) {
1820      struct gl_bindless_image *image = &prog->sh.BindlessImages[i];
1821
1822      if (image->bound)
1823         return;
1824   }
1825   prog->sh.HasBoundBindlessImage = false;
1826}
1827
1828/**
1829 * Called via glUniformHandleui64*ARB() functions.
1830 */
1831extern "C" void
1832_mesa_uniform_handle(GLint location, GLsizei count, const GLvoid *values,
1833                     struct gl_context *ctx, struct gl_shader_program *shProg)
1834{
1835   unsigned offset;
1836   struct gl_uniform_storage *uni;
1837
1838   if (_mesa_is_no_error_enabled(ctx)) {
1839      /* From Section 7.6 (UNIFORM VARIABLES) of the OpenGL 4.5 spec:
1840       *
1841       *   "If the value of location is -1, the Uniform* commands will
1842       *   silently ignore the data passed in, and the current uniform values
1843       *   will not be changed.
1844       */
1845      if (location == -1)
1846         return;
1847
1848      uni = shProg->UniformRemapTable[location];
1849      if (!uni || uni == INACTIVE_UNIFORM_EXPLICIT_LOCATION)
1850         return;
1851
1852      /* The array index specified by the uniform location is just the
1853       * uniform location minus the base location of of the uniform.
1854       */
1855      assert(uni->array_elements > 0 || location == (int)uni->remap_location);
1856      offset = location - uni->remap_location;
1857   } else {
1858      uni = validate_uniform_parameters(location, count, &offset,
1859                                        ctx, shProg, "glUniformHandleui64*ARB");
1860      if (!uni)
1861         return;
1862
1863      if (!uni->is_bindless) {
1864         /* From section "Errors" of the ARB_bindless_texture spec:
1865          *
1866          * "The error INVALID_OPERATION is generated by
1867          *  UniformHandleui64{v}ARB if the sampler or image uniform being
1868          *  updated has the "bound_sampler" or "bound_image" layout qualifier."
1869          *
1870          * From section 4.4.6 of the ARB_bindless_texture spec:
1871          *
1872          * "In the absence of these qualifiers, sampler and image uniforms are
1873          *  considered "bound". Additionally, if GL_ARB_bindless_texture is
1874          *  not enabled, these uniforms are considered "bound"."
1875          */
1876         _mesa_error(ctx, GL_INVALID_OPERATION,
1877                     "glUniformHandleui64*ARB(non-bindless sampler/image uniform)");
1878         return;
1879      }
1880   }
1881
1882   const unsigned components = uni->type->vector_elements;
1883   const int size_mul = 2;
1884
1885   if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
1886      log_uniform(values, GLSL_TYPE_UINT64, components, 1, count,
1887                  false, shProg, location, uni);
1888   }
1889
1890   /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
1891    *
1892    *     "When loading N elements starting at an arbitrary position k in a
1893    *     uniform declared as an array, elements k through k + N - 1 in the
1894    *     array will be replaced with the new values. Values for any array
1895    *     element that exceeds the highest array element index used, as
1896    *     reported by GetActiveUniform, will be ignored by the GL."
1897    *
1898    * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
1899    * will have already generated an error.
1900    */
1901   if (uni->array_elements != 0) {
1902      count = MIN2(count, (int) (uni->array_elements - offset));
1903   }
1904
1905
1906   /* Store the data in the "actual type" backing storage for the uniform.
1907    */
1908   if (ctx->Const.PackedDriverUniformStorage) {
1909      bool flushed = false;
1910
1911      for (unsigned s = 0; s < uni->num_driver_storage; s++) {
1912         void *storage = (gl_constant_value *)
1913            uni->driver_storage[s].data + (size_mul * offset * components);
1914         unsigned size = sizeof(uni->storage[0]) * components * count * size_mul;
1915
1916         if (!memcmp(storage, values, size))
1917            continue;
1918
1919         if (!flushed) {
1920            _mesa_flush_vertices_for_uniforms(ctx, uni);
1921            flushed = true;
1922         }
1923         memcpy(storage, values, size);
1924      }
1925      if (!flushed)
1926         return;
1927   } else {
1928      void *storage = &uni->storage[size_mul * components * offset];
1929      unsigned size = sizeof(uni->storage[0]) * components * count * size_mul;
1930
1931      if (!memcmp(storage, values, size))
1932         return;
1933
1934      _mesa_flush_vertices_for_uniforms(ctx, uni);
1935      memcpy(storage, values, size);
1936      _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
1937   }
1938
1939   if (uni->type->is_sampler()) {
1940      /* Mark this bindless sampler as not bound to a texture unit because
1941       * it refers to a texture handle.
1942       */
1943      for (int i = 0; i < MESA_SHADER_STAGES; i++) {
1944         struct gl_linked_shader *const sh = shProg->_LinkedShaders[i];
1945
1946         /* If the shader stage doesn't use the sampler uniform, skip this. */
1947         if (!uni->opaque[i].active)
1948            continue;
1949
1950         for (int j = 0; j < count; j++) {
1951            unsigned unit = uni->opaque[i].index + offset + j;
1952            struct gl_bindless_sampler *sampler =
1953               &sh->Program->sh.BindlessSamplers[unit];
1954
1955            sampler->bound = false;
1956         }
1957
1958         update_bound_bindless_sampler_flag(sh->Program);
1959      }
1960   }
1961
1962   if (uni->type->is_image()) {
1963      /* Mark this bindless image as not bound to an image unit because it
1964       * refers to a texture handle.
1965       */
1966      for (int i = 0; i < MESA_SHADER_STAGES; i++) {
1967         struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
1968
1969         /* If the shader stage doesn't use the sampler uniform, skip this. */
1970         if (!uni->opaque[i].active)
1971            continue;
1972
1973         for (int j = 0; j < count; j++) {
1974            unsigned unit = uni->opaque[i].index + offset + j;
1975            struct gl_bindless_image *image =
1976               &sh->Program->sh.BindlessImages[unit];
1977
1978            image->bound = false;
1979         }
1980
1981         update_bound_bindless_image_flag(sh->Program);
1982      }
1983   }
1984}
1985
1986extern "C" bool
1987_mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
1988				 char *errMsg, size_t errMsgLength)
1989{
1990   /* Shader does not have samplers. */
1991   if (shProg->data->NumUniformStorage == 0)
1992      return true;
1993
1994   if (!shProg->SamplersValidated) {
1995      snprintf(errMsg, errMsgLength,
1996                     "active samplers with a different type "
1997                     "refer to the same texture image unit");
1998      return false;
1999   }
2000   return true;
2001}
2002
2003extern "C" bool
2004_mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline)
2005{
2006   /* Section 2.11.11 (Shader Execution), subheading "Validation," of the
2007    * OpenGL 4.1 spec says:
2008    *
2009    *     "[INVALID_OPERATION] is generated by any command that transfers
2010    *     vertices to the GL if:
2011    *
2012    *         ...
2013    *
2014    *         - Any two active samplers in the current program object are of
2015    *           different types, but refer to the same texture image unit.
2016    *
2017    *         - The number of active samplers in the program exceeds the
2018    *           maximum number of texture image units allowed."
2019    */
2020
2021   GLbitfield mask;
2022   GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
2023   unsigned active_samplers = 0;
2024   const struct gl_program **prog =
2025      (const struct gl_program **) pipeline->CurrentProgram;
2026
2027
2028   memset(TexturesUsed, 0, sizeof(TexturesUsed));
2029
2030   for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
2031      if (!prog[idx])
2032         continue;
2033
2034      mask = prog[idx]->SamplersUsed;
2035      while (mask) {
2036         const int s = u_bit_scan(&mask);
2037         GLuint unit = prog[idx]->SamplerUnits[s];
2038         GLuint tgt = prog[idx]->sh.SamplerTargets[s];
2039
2040         /* FIXME: Samplers are initialized to 0 and Mesa doesn't do a
2041          * great job of eliminating unused uniforms currently so for now
2042          * don't throw an error if two sampler types both point to 0.
2043          */
2044         if (unit == 0)
2045            continue;
2046
2047         if (TexturesUsed[unit] & ~(1 << tgt)) {
2048            pipeline->InfoLog =
2049               ralloc_asprintf(pipeline,
2050                     "Program %d: "
2051                     "Texture unit %d is accessed with 2 different types",
2052                     prog[idx]->Id, unit);
2053            return false;
2054         }
2055
2056         TexturesUsed[unit] |= (1 << tgt);
2057      }
2058
2059      active_samplers += prog[idx]->info.num_textures;
2060   }
2061
2062   if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) {
2063      pipeline->InfoLog =
2064         ralloc_asprintf(pipeline,
2065                         "the number of active samplers %d exceed the "
2066                         "maximum %d",
2067                         active_samplers, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
2068      return false;
2069   }
2070
2071   return true;
2072}
2073