• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
53 extern "C" void
_mesa_GetActiveUniform_impl(GLuint program,GLuint index,GLsizei maxLength,GLsizei * length,GLint * size,GLenum * type,GLcharARB * nameOut,bool glthread)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 
96 extern "C" void GLAPIENTRY
_mesa_GetActiveUniform(GLuint program,GLuint index,GLsizei maxLength,GLsizei * length,GLint * size,GLenum * type,GLcharARB * nameOut)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 
105 static GLenum
resource_prop_from_uniform_prop(GLenum uni_prop)106 resource_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 
132 extern "C" void GLAPIENTRY
_mesa_GetActiveUniformsiv(GLuint program,GLsizei uniformCount,const GLuint * uniformIndices,GLenum pname,GLint * params)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 
183 static struct gl_uniform_storage *
validate_uniform_parameters(GLint location,GLsizei count,unsigned * array_index,struct gl_context * ctx,struct gl_shader_program * shProg,const char * caller)184 validate_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  */
302 extern "C" void
_mesa_get_uniform(struct gl_context * ctx,GLuint program,GLint location,GLsizei bufSize,enum glsl_base_type returnType,GLvoid * paramsOut)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 
730 static void
log_uniform(const void * values,enum glsl_base_type basicType,unsigned rows,unsigned cols,unsigned count,bool transpose,const struct gl_shader_program * shProg,GLint location,const struct gl_uniform_storage * uni)731 log_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
789 static void
790 log_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  */
830 extern "C" void
_mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage * uni,unsigned array_index,unsigned count)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 
926 static void
associate_uniform_storage(struct gl_context * ctx,struct gl_shader_program * shader_program,struct gl_program * prog)927 associate_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 
1078 void
_mesa_ensure_and_associate_uniform_storage(struct gl_context * ctx,struct gl_shader_program * shader_program,struct gl_program * prog,unsigned required_space)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  */
1100 static const char *
glsl_type_name(enum glsl_base_type type)1101 glsl_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 
1140 static struct gl_uniform_storage *
validate_uniform(GLint location,GLsizei count,const GLvoid * values,unsigned * offset,struct gl_context * ctx,struct gl_shader_program * shProg,enum glsl_base_type basicType,unsigned src_components)1141 validate_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 
1257 void
_mesa_flush_vertices_for_uniforms(struct gl_context * ctx,const struct gl_uniform_storage * uni)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 
1283 static bool
copy_uniforms_to_storage(gl_constant_value * storage,struct gl_uniform_storage * uni,struct gl_context * ctx,GLsizei count,const GLvoid * values,const int size_mul,const unsigned offset,const unsigned components,enum glsl_base_type basicType,bool flush)1284 copy_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  */
1432 extern "C" void
_mesa_uniform(GLint location,GLsizei count,const GLvoid * values,struct gl_context * ctx,struct gl_shader_program * shProg,enum glsl_base_type basicType,unsigned src_components)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 
1622 static bool
copy_uniform_matrix_to_storage(struct gl_context * ctx,gl_constant_value * storage,struct gl_uniform_storage * const uni,unsigned count,const void * values,const unsigned size_mul,const unsigned offset,const unsigned components,const unsigned vectors,bool transpose,unsigned cols,unsigned rows,enum glsl_base_type basicType,bool flush)1623 copy_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  */
1840 extern "C" void
_mesa_uniform_matrix(GLint location,GLsizei count,GLboolean transpose,const void * values,struct gl_context * ctx,struct gl_shader_program * shProg,GLuint cols,GLuint rows,enum glsl_base_type basicType)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 
1967 static void
update_bound_bindless_sampler_flag(struct gl_program * prog)1968 update_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 
1984 static void
update_bound_bindless_image_flag(struct gl_program * prog)1985 update_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  */
2004 extern "C" void
_mesa_uniform_handle(GLint location,GLsizei count,const GLvoid * values,struct gl_context * ctx,struct gl_shader_program * shProg)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 
2159 extern "C" bool
_mesa_sampler_uniforms_are_valid(const struct gl_shader_program * shProg,char * errMsg,size_t errMsgLength)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 
2176 extern "C" bool
_mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object * pipeline)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