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