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