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