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