• 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/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 *src;
340       if (ctx->Const.PackedDriverUniformStorage &&
341           (uni->is_bindless || !uni->type->contains_opaque())) {
342          src = (gl_constant_value *) uni->driver_storage[0].data +
343             (offset * elements * dmul);
344       } else {
345          src = &uni->storage[offset * elements * dmul];
346       }
347 
348       assert(returnType == GLSL_TYPE_FLOAT || returnType == GLSL_TYPE_INT ||
349              returnType == GLSL_TYPE_UINT || returnType == GLSL_TYPE_DOUBLE ||
350              returnType == GLSL_TYPE_UINT64 || returnType == GLSL_TYPE_INT64);
351 
352       /* doubles have a different size than the other 3 types */
353       unsigned bytes = sizeof(src[0]) * elements * rmul;
354       if (bufSize < 0 || bytes > (unsigned) bufSize) {
355          _mesa_error(ctx, GL_INVALID_OPERATION,
356                      "glGetnUniform*vARB(out of bounds: bufSize is %d,"
357                      " but %u bytes are required)", bufSize, bytes);
358          return;
359       }
360 
361       /* If the return type and the uniform's native type are "compatible,"
362        * just memcpy the data.  If the types are not compatible, perform a
363        * slower convert-and-copy process.
364        */
365       if (returnType == uni->type->base_type ||
366           ((returnType == GLSL_TYPE_INT || returnType == GLSL_TYPE_UINT) &&
367            (uni->type->is_sampler() || uni->type->is_image())) ||
368           (returnType == GLSL_TYPE_UINT64 && uni->is_bindless)) {
369          memcpy(paramsOut, src, bytes);
370       } else {
371          union gl_constant_value *const dst =
372             (union gl_constant_value *) paramsOut;
373          /* This code could be optimized by putting the loop inside the switch
374           * statements.  However, this is not expected to be
375           * performance-critical code.
376           */
377          for (unsigned i = 0; i < elements; i++) {
378             int sidx = i * dmul;
379             int didx = i * rmul;
380 
381             switch (returnType) {
382             case GLSL_TYPE_FLOAT:
383                switch (uni->type->base_type) {
384                case GLSL_TYPE_UINT:
385                   dst[didx].f = (float) src[sidx].u;
386                   break;
387                case GLSL_TYPE_INT:
388                case GLSL_TYPE_SAMPLER:
389                case GLSL_TYPE_IMAGE:
390                   dst[didx].f = (float) src[sidx].i;
391                   break;
392                case GLSL_TYPE_BOOL:
393                   dst[didx].f = src[sidx].i ? 1.0f : 0.0f;
394                   break;
395                case GLSL_TYPE_DOUBLE: {
396                   double tmp;
397                   memcpy(&tmp, &src[sidx].f, sizeof(tmp));
398                   dst[didx].f = tmp;
399                   break;
400                }
401                case GLSL_TYPE_UINT64: {
402                   uint64_t tmp;
403                   memcpy(&tmp, &src[sidx].u, sizeof(tmp));
404                   dst[didx].f = tmp;
405                   break;
406                 }
407                case GLSL_TYPE_INT64: {
408                   uint64_t tmp;
409                   memcpy(&tmp, &src[sidx].i, sizeof(tmp));
410                   dst[didx].f = tmp;
411                   break;
412                }
413                default:
414                   assert(!"Should not get here.");
415                   break;
416                }
417                break;
418 
419             case GLSL_TYPE_DOUBLE:
420                switch (uni->type->base_type) {
421                case GLSL_TYPE_UINT: {
422                   double tmp = src[sidx].u;
423                   memcpy(&dst[didx].f, &tmp, sizeof(tmp));
424                   break;
425                }
426                case GLSL_TYPE_INT:
427                case GLSL_TYPE_SAMPLER:
428                case GLSL_TYPE_IMAGE: {
429                   double tmp = src[sidx].i;
430                   memcpy(&dst[didx].f, &tmp, sizeof(tmp));
431                   break;
432                }
433                case GLSL_TYPE_BOOL: {
434                   double tmp = src[sidx].i ? 1.0 : 0.0;
435                   memcpy(&dst[didx].f, &tmp, sizeof(tmp));
436                   break;
437                }
438                case GLSL_TYPE_FLOAT: {
439                   double tmp = src[sidx].f;
440                   memcpy(&dst[didx].f, &tmp, sizeof(tmp));
441                   break;
442                }
443                case GLSL_TYPE_UINT64: {
444                   uint64_t tmpu;
445                   double tmp;
446                   memcpy(&tmpu, &src[sidx].u, sizeof(tmpu));
447                   tmp = tmpu;
448                   memcpy(&dst[didx].f, &tmp, sizeof(tmp));
449                   break;
450                }
451                case GLSL_TYPE_INT64: {
452                   int64_t tmpi;
453                   double tmp;
454                   memcpy(&tmpi, &src[sidx].i, sizeof(tmpi));
455                   tmp = tmpi;
456                   memcpy(&dst[didx].f, &tmp, sizeof(tmp));
457                   break;
458                }
459                default:
460                   assert(!"Should not get here.");
461                   break;
462                }
463                break;
464 
465             case GLSL_TYPE_INT:
466                switch (uni->type->base_type) {
467                case GLSL_TYPE_FLOAT:
468                   /* While the GL 3.2 core spec doesn't explicitly
469                    * state how conversion of float uniforms to integer
470                    * values works, in section 6.2 "State Tables" on
471                    * page 267 it says:
472                    *
473                    *     "Unless otherwise specified, when floating
474                    *      point state is returned as integer values or
475                    *      integer state is returned as floating-point
476                    *      values it is converted in the fashion
477                    *      described in section 6.1.2"
478                    *
479                    * That section, on page 248, says:
480                    *
481                    *     "If GetIntegerv or GetInteger64v are called,
482                    *      a floating-point value is rounded to the
483                    *      nearest integer..."
484                    */
485                   dst[didx].i = (int64_t) roundf(src[sidx].f);
486                   break;
487                case GLSL_TYPE_BOOL:
488                   dst[didx].i = src[sidx].i ? 1 : 0;
489                   break;
490                case GLSL_TYPE_UINT:
491                   dst[didx].i = MIN2(src[sidx].i, INT_MAX);
492                   break;
493                case GLSL_TYPE_DOUBLE: {
494                   double tmp;
495                   memcpy(&tmp, &src[sidx].f, sizeof(tmp));
496                   dst[didx].i = (int64_t) round(tmp);
497                   break;
498                }
499                case GLSL_TYPE_UINT64: {
500                   uint64_t tmp;
501                   memcpy(&tmp, &src[sidx].u, sizeof(tmp));
502                   dst[didx].i = tmp;
503                   break;
504                }
505                case GLSL_TYPE_INT64: {
506                   int64_t tmp;
507                   memcpy(&tmp, &src[sidx].i, sizeof(tmp));
508                   dst[didx].i = tmp;
509                   break;
510                }
511                default:
512                   assert(!"Should not get here.");
513                   break;
514                }
515                break;
516 
517             case GLSL_TYPE_UINT:
518                switch (uni->type->base_type) {
519                case GLSL_TYPE_FLOAT:
520                   /* The spec isn't terribly clear how to handle negative
521                    * values with an unsigned return type.
522                    *
523                    * GL 4.5 section 2.2.2 ("Data Conversions for State
524                    * Query Commands") says:
525                    *
526                    * "If a value is so large in magnitude that it cannot be
527                    *  represented by the returned data type, then the nearest
528                    *  value representable using the requested type is
529                    *  returned."
530                    */
531                   dst[didx].u = src[sidx].f < 0.0f ?
532                      0u : (uint32_t) roundf(src[sidx].f);
533                   break;
534                case GLSL_TYPE_BOOL:
535                   dst[didx].i = src[sidx].i ? 1 : 0;
536                   break;
537                case GLSL_TYPE_INT:
538                   dst[didx].i = MAX2(src[sidx].i, 0);
539                   break;
540                case GLSL_TYPE_DOUBLE: {
541                   double tmp;
542                   memcpy(&tmp, &src[sidx].f, sizeof(tmp));
543                   dst[didx].u = tmp < 0.0 ? 0u : (uint32_t) round(tmp);
544                   break;
545                }
546                case GLSL_TYPE_UINT64: {
547                   uint64_t tmp;
548                   memcpy(&tmp, &src[sidx].u, sizeof(tmp));
549                   dst[didx].i = MIN2(tmp, INT_MAX);
550                   break;
551                }
552                case GLSL_TYPE_INT64: {
553                   int64_t tmp;
554                   memcpy(&tmp, &src[sidx].i, sizeof(tmp));
555                   dst[didx].i = MAX2(tmp, 0);
556                   break;
557                }
558                default:
559                   unreachable("invalid uniform type");
560                }
561                break;
562 
563             case GLSL_TYPE_INT64:
564                switch (uni->type->base_type) {
565                case GLSL_TYPE_UINT: {
566                   uint64_t tmp = src[sidx].u;
567                   memcpy(&dst[didx].u, &tmp, sizeof(tmp));
568                   break;
569                }
570                case GLSL_TYPE_INT:
571                case GLSL_TYPE_SAMPLER:
572                case GLSL_TYPE_IMAGE: {
573                   int64_t tmp = src[sidx].i;
574                   memcpy(&dst[didx].u, &tmp, sizeof(tmp));
575                   break;
576                }
577                case GLSL_TYPE_BOOL: {
578                   int64_t tmp = src[sidx].i ? 1.0f : 0.0f;
579                   memcpy(&dst[didx].u, &tmp, sizeof(tmp));
580                   break;
581                }
582                case GLSL_TYPE_UINT64: {
583                   uint64_t u64;
584                   memcpy(&u64, &src[sidx].u, sizeof(u64));
585                   int64_t tmp = MIN2(u64, INT_MAX);
586                   memcpy(&dst[didx].u, &tmp, sizeof(tmp));
587                   break;
588                }
589                case GLSL_TYPE_FLOAT: {
590                   int64_t tmp = (int64_t) roundf(src[sidx].f);
591                   memcpy(&dst[didx].u, &tmp, sizeof(tmp));
592                   break;
593                }
594                case GLSL_TYPE_DOUBLE: {
595                   double d;
596                   memcpy(&d, &src[sidx].f, sizeof(d));
597                   int64_t tmp = (int64_t) round(d);
598                   memcpy(&dst[didx].u, &tmp, sizeof(tmp));
599                   break;
600                }
601                default:
602                   assert(!"Should not get here.");
603                   break;
604                }
605                break;
606 
607             case GLSL_TYPE_UINT64:
608                switch (uni->type->base_type) {
609                case GLSL_TYPE_UINT: {
610                   uint64_t tmp = src[sidx].u;
611                   memcpy(&dst[didx].u, &tmp, sizeof(tmp));
612                   break;
613                }
614                case GLSL_TYPE_INT:
615                case GLSL_TYPE_SAMPLER:
616                case GLSL_TYPE_IMAGE: {
617                   int64_t tmp = MAX2(src[sidx].i, 0);
618                   memcpy(&dst[didx].u, &tmp, sizeof(tmp));
619                   break;
620                }
621                case GLSL_TYPE_BOOL: {
622                   int64_t tmp = src[sidx].i ? 1.0f : 0.0f;
623                   memcpy(&dst[didx].u, &tmp, sizeof(tmp));
624                   break;
625                }
626                case GLSL_TYPE_INT64: {
627                   uint64_t i64;
628                   memcpy(&i64, &src[sidx].i, sizeof(i64));
629                   uint64_t tmp = MAX2(i64, 0);
630                   memcpy(&dst[didx].u, &tmp, sizeof(tmp));
631                   break;
632                }
633                case GLSL_TYPE_FLOAT: {
634                   uint64_t tmp = src[sidx].f < 0.0f ?
635                      0ull : (uint64_t) roundf(src[sidx].f);
636                   memcpy(&dst[didx].u, &tmp, sizeof(tmp));
637                   break;
638                }
639                case GLSL_TYPE_DOUBLE: {
640                   double d;
641                   memcpy(&d, &src[sidx].f, sizeof(d));
642                   uint64_t tmp = (d < 0.0) ? 0ull : (uint64_t) round(d);
643                   memcpy(&dst[didx].u, &tmp, sizeof(tmp));
644                   break;
645                }
646                default:
647                   assert(!"Should not get here.");
648                   break;
649                }
650                break;
651 
652             default:
653                assert(!"Should not get here.");
654                break;
655             }
656          }
657       }
658    }
659 }
660 
661 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)662 log_uniform(const void *values, enum glsl_base_type basicType,
663 	    unsigned rows, unsigned cols, unsigned count,
664 	    bool transpose,
665 	    const struct gl_shader_program *shProg,
666 	    GLint location,
667 	    const struct gl_uniform_storage *uni)
668 {
669 
670    const union gl_constant_value *v = (const union gl_constant_value *) values;
671    const unsigned elems = rows * cols * count;
672    const char *const extra = (cols == 1) ? "uniform" : "uniform matrix";
673 
674    printf("Mesa: set program %u %s \"%s\" (loc %d, type \"%s\", "
675 	  "transpose = %s) to: ",
676 	  shProg->Name, extra, uni->name, location, uni->type->name,
677 	  transpose ? "true" : "false");
678    for (unsigned i = 0; i < elems; i++) {
679       if (i != 0 && ((i % rows) == 0))
680 	 printf(", ");
681 
682       switch (basicType) {
683       case GLSL_TYPE_UINT:
684 	 printf("%u ", v[i].u);
685 	 break;
686       case GLSL_TYPE_INT:
687 	 printf("%d ", v[i].i);
688 	 break;
689       case GLSL_TYPE_UINT64: {
690          uint64_t tmp;
691          memcpy(&tmp, &v[i * 2].u, sizeof(tmp));
692          printf("%" PRIu64 " ", tmp);
693          break;
694       }
695       case GLSL_TYPE_INT64: {
696          int64_t tmp;
697          memcpy(&tmp, &v[i * 2].u, sizeof(tmp));
698          printf("%" PRId64 " ", tmp);
699          break;
700       }
701       case GLSL_TYPE_FLOAT:
702 	 printf("%g ", v[i].f);
703 	 break;
704       case GLSL_TYPE_DOUBLE: {
705          double tmp;
706          memcpy(&tmp, &v[i * 2].f, sizeof(tmp));
707          printf("%g ", tmp);
708          break;
709       }
710       default:
711 	 assert(!"Should not get here.");
712 	 break;
713       }
714    }
715    printf("\n");
716    fflush(stdout);
717 }
718 
719 #if 0
720 static void
721 log_program_parameters(const struct gl_shader_program *shProg)
722 {
723    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
724       if (shProg->_LinkedShaders[i] == NULL)
725 	 continue;
726 
727       const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program;
728 
729       printf("Program %d %s shader parameters:\n",
730              shProg->Name, _mesa_shader_stage_to_string(i));
731       for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) {
732          unsigned pvo = prog->Parameters->ParameterValueOffset[j];
733          printf("%s: %u %p %f %f %f %f\n",
734 		prog->Parameters->Parameters[j].Name,
735                 pvo,
736                 prog->Parameters->ParameterValues + pvo,
737                 prog->Parameters->ParameterValues[pvo].f,
738                 prog->Parameters->ParameterValues[pvo + 1].f,
739                 prog->Parameters->ParameterValues[pvo + 2].f,
740                 prog->Parameters->ParameterValues[pvo + 3].f);
741       }
742    }
743    fflush(stdout);
744 }
745 #endif
746 
747 /**
748  * Propagate some values from uniform backing storage to driver storage
749  *
750  * Values propagated from uniform backing storage to driver storage
751  * have all format / type conversions previously requested by the
752  * driver applied.  This function is most often called by the
753  * implementations of \c glUniform1f, etc. and \c glUniformMatrix2f,
754  * etc.
755  *
756  * \param uni          Uniform whose data is to be propagated to driver storage
757  * \param array_index  If \c uni is an array, this is the element of
758  *                     the array to be propagated.
759  * \param count        Number of array elements to propagate.
760  */
761 extern "C" void
_mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage * uni,unsigned array_index,unsigned count)762 _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni,
763 					   unsigned array_index,
764 					   unsigned count)
765 {
766    unsigned i;
767 
768    const unsigned components = uni->type->vector_elements;
769    const unsigned vectors = uni->type->matrix_columns;
770    const int dmul = uni->type->is_64bit() ? 2 : 1;
771 
772    /* Store the data in the driver's requested type in the driver's storage
773     * areas.
774     */
775    unsigned src_vector_byte_stride = components * 4 * dmul;
776 
777    for (i = 0; i < uni->num_driver_storage; i++) {
778       struct gl_uniform_driver_storage *const store = &uni->driver_storage[i];
779       uint8_t *dst = (uint8_t *) store->data;
780       const unsigned extra_stride =
781 	 store->element_stride - (vectors * store->vector_stride);
782       const uint8_t *src =
783 	 (uint8_t *) (&uni->storage[array_index * (dmul * components * vectors)].i);
784 
785 #if 0
786       printf("%s: %p[%d] components=%u vectors=%u count=%u vector_stride=%u "
787 	     "extra_stride=%u\n",
788 	     __func__, dst, array_index, components,
789 	     vectors, count, store->vector_stride, extra_stride);
790 #endif
791 
792       dst += array_index * store->element_stride;
793 
794       switch (store->format) {
795       case uniform_native: {
796 	 unsigned j;
797 	 unsigned v;
798 
799 	 if (src_vector_byte_stride == store->vector_stride) {
800 	    if (extra_stride) {
801 	       for (j = 0; j < count; j++) {
802 	          memcpy(dst, src, src_vector_byte_stride * vectors);
803 	          src += src_vector_byte_stride * vectors;
804 	          dst += store->vector_stride * vectors;
805 
806 	          dst += extra_stride;
807 	       }
808 	    } else {
809 	       /* Unigine Heaven benchmark gets here */
810 	       memcpy(dst, src, src_vector_byte_stride * vectors * count);
811 	       src += src_vector_byte_stride * vectors * count;
812 	       dst += store->vector_stride * vectors * count;
813 	    }
814 	 } else {
815 	    for (j = 0; j < count; j++) {
816 	       for (v = 0; v < vectors; v++) {
817 	          memcpy(dst, src, src_vector_byte_stride);
818 	          src += src_vector_byte_stride;
819 	          dst += store->vector_stride;
820 	       }
821 
822 	       dst += extra_stride;
823 	    }
824 	 }
825 	 break;
826       }
827 
828       case uniform_int_float: {
829 	 const int *isrc = (const int *) src;
830 	 unsigned j;
831 	 unsigned v;
832 	 unsigned c;
833 
834 	 for (j = 0; j < count; j++) {
835 	    for (v = 0; v < vectors; v++) {
836 	       for (c = 0; c < components; c++) {
837 		  ((float *) dst)[c] = (float) *isrc;
838 		  isrc++;
839 	       }
840 
841 	       dst += store->vector_stride;
842 	    }
843 
844 	    dst += extra_stride;
845 	 }
846 	 break;
847       }
848 
849       default:
850 	 assert(!"Should not get here.");
851 	 break;
852       }
853    }
854 }
855 
856 
857 /**
858  * Return printable string for a given GLSL_TYPE_x
859  */
860 static const char *
glsl_type_name(enum glsl_base_type type)861 glsl_type_name(enum glsl_base_type type)
862 {
863    switch (type) {
864    case GLSL_TYPE_UINT:
865       return "uint";
866    case GLSL_TYPE_INT:
867       return "int";
868    case GLSL_TYPE_FLOAT:
869       return "float";
870    case GLSL_TYPE_DOUBLE:
871       return "double";
872    case GLSL_TYPE_UINT64:
873       return "uint64";
874    case GLSL_TYPE_INT64:
875       return "int64";
876    case GLSL_TYPE_BOOL:
877       return "bool";
878    case GLSL_TYPE_SAMPLER:
879       return "sampler";
880    case GLSL_TYPE_IMAGE:
881       return "image";
882    case GLSL_TYPE_ATOMIC_UINT:
883       return "atomic_uint";
884    case GLSL_TYPE_STRUCT:
885       return "struct";
886    case GLSL_TYPE_INTERFACE:
887       return "interface";
888    case GLSL_TYPE_ARRAY:
889       return "array";
890    case GLSL_TYPE_VOID:
891       return "void";
892    case GLSL_TYPE_ERROR:
893       return "error";
894    default:
895       return "other";
896    }
897 }
898 
899 
900 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)901 validate_uniform(GLint location, GLsizei count, const GLvoid *values,
902                  unsigned *offset, struct gl_context *ctx,
903                  struct gl_shader_program *shProg,
904                  enum glsl_base_type basicType, unsigned src_components)
905 {
906    struct gl_uniform_storage *const uni =
907       validate_uniform_parameters(location, count, offset,
908                                   ctx, shProg, "glUniform");
909    if (uni == NULL)
910       return NULL;
911 
912    if (uni->type->is_matrix()) {
913       /* Can't set matrix uniforms (like mat4) with glUniform */
914       _mesa_error(ctx, GL_INVALID_OPERATION,
915                   "glUniform%u(uniform \"%s\"@%d is matrix)",
916                   src_components, uni->name, location);
917       return NULL;
918    }
919 
920    /* Verify that the types are compatible. */
921    const unsigned components = uni->type->vector_elements;
922 
923    if (components != src_components) {
924       /* glUniformN() must match float/vecN type */
925       _mesa_error(ctx, GL_INVALID_OPERATION,
926                   "glUniform%u(\"%s\"@%u has %u components, not %u)",
927                   src_components, uni->name, location,
928                   components, src_components);
929       return NULL;
930    }
931 
932    bool match;
933    switch (uni->type->base_type) {
934    case GLSL_TYPE_BOOL:
935       match = (basicType != GLSL_TYPE_DOUBLE);
936       break;
937    case GLSL_TYPE_SAMPLER:
938       match = (basicType == GLSL_TYPE_INT);
939       break;
940    case GLSL_TYPE_IMAGE:
941       match = (basicType == GLSL_TYPE_INT && _mesa_is_desktop_gl(ctx));
942       break;
943    default:
944       match = (basicType == uni->type->base_type);
945       break;
946    }
947 
948    if (!match) {
949       _mesa_error(ctx, GL_INVALID_OPERATION,
950                   "glUniform%u(\"%s\"@%d is %s, not %s)",
951                   src_components, uni->name, location,
952                   glsl_type_name(uni->type->base_type),
953                   glsl_type_name(basicType));
954       return NULL;
955    }
956 
957    if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
958       log_uniform(values, basicType, components, 1, count,
959                   false, shProg, location, uni);
960    }
961 
962    /* Page 100 (page 116 of the PDF) of the OpenGL 3.0 spec says:
963     *
964     *     "Setting a sampler's value to i selects texture image unit number
965     *     i. The values of i range from zero to the implementation- dependent
966     *     maximum supported number of texture image units."
967     *
968     * In addition, table 2.3, "Summary of GL errors," on page 17 (page 33 of
969     * the PDF) says:
970     *
971     *     "Error         Description                    Offending command
972     *                                                   ignored?
973     *     ...
974     *     INVALID_VALUE  Numeric argument out of range  Yes"
975     *
976     * Based on that, when an invalid sampler is specified, we generate a
977     * GL_INVALID_VALUE error and ignore the command.
978     */
979    if (uni->type->is_sampler()) {
980       for (int i = 0; i < count; i++) {
981          const unsigned texUnit = ((unsigned *) values)[i];
982 
983          /* check that the sampler (tex unit index) is legal */
984          if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
985             _mesa_error(ctx, GL_INVALID_VALUE,
986                         "glUniform1i(invalid sampler/tex unit index for "
987                         "uniform %d)", location);
988             return NULL;
989          }
990       }
991       /* We need to reset the validate flag on changes to samplers in case
992        * two different sampler types are set to the same texture unit.
993        */
994       ctx->_Shader->Validated = GL_FALSE;
995    }
996 
997    if (uni->type->is_image()) {
998       for (int i = 0; i < count; i++) {
999          const int unit = ((GLint *) values)[i];
1000 
1001          /* check that the image unit is legal */
1002          if (unit < 0 || unit >= (int)ctx->Const.MaxImageUnits) {
1003             _mesa_error(ctx, GL_INVALID_VALUE,
1004                         "glUniform1i(invalid image unit index for uniform %d)",
1005                         location);
1006             return NULL;
1007          }
1008       }
1009    }
1010 
1011    return uni;
1012 }
1013 
1014 void
_mesa_flush_vertices_for_uniforms(struct gl_context * ctx,const struct gl_uniform_storage * uni)1015 _mesa_flush_vertices_for_uniforms(struct gl_context *ctx,
1016                                   const struct gl_uniform_storage *uni)
1017 {
1018    /* Opaque uniforms have no storage unless they are bindless */
1019    if (!uni->is_bindless && uni->type->contains_opaque()) {
1020       FLUSH_VERTICES(ctx, 0);
1021       return;
1022    }
1023 
1024    uint64_t new_driver_state = 0;
1025    unsigned mask = uni->active_shader_mask;
1026 
1027    while (mask) {
1028       unsigned index = u_bit_scan(&mask);
1029 
1030       assert(index < MESA_SHADER_STAGES);
1031       new_driver_state |= ctx->DriverFlags.NewShaderConstants[index];
1032    }
1033 
1034    FLUSH_VERTICES(ctx, new_driver_state ? 0 : _NEW_PROGRAM_CONSTANTS);
1035    ctx->NewDriverState |= new_driver_state;
1036 }
1037 
1038 static void
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)1039 copy_uniforms_to_storage(gl_constant_value *storage,
1040                          struct gl_uniform_storage *uni,
1041                          struct gl_context *ctx, GLsizei count,
1042                          const GLvoid *values, const int size_mul,
1043                          const unsigned offset, const unsigned components,
1044                          enum glsl_base_type basicType)
1045 {
1046    bool copy_as_uint64 = uni->is_bindless &&
1047                          (uni->type->is_sampler() || uni->type->is_image());
1048    if (!uni->type->is_boolean() && !copy_as_uint64) {
1049       memcpy(storage, values,
1050              sizeof(storage[0]) * components * count * size_mul);
1051    } else if (copy_as_uint64) {
1052       const union gl_constant_value *src =
1053          (const union gl_constant_value *) values;
1054       GLuint64 *dst = (GLuint64 *)&storage->i;
1055       const unsigned elems = components * count;
1056 
1057       for (unsigned i = 0; i < elems; i++) {
1058          dst[i] = src[i].i;
1059       }
1060    } else {
1061       const union gl_constant_value *src =
1062          (const union gl_constant_value *) values;
1063       union gl_constant_value *dst = storage;
1064       const unsigned elems = components * count;
1065 
1066       for (unsigned i = 0; i < elems; i++) {
1067          if (basicType == GLSL_TYPE_FLOAT) {
1068             dst[i].i = src[i].f != 0.0f ? ctx->Const.UniformBooleanTrue : 0;
1069          } else {
1070             dst[i].i = src[i].i != 0    ? ctx->Const.UniformBooleanTrue : 0;
1071          }
1072       }
1073    }
1074 }
1075 
1076 
1077 /**
1078  * Called via glUniform*() functions.
1079  */
1080 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)1081 _mesa_uniform(GLint location, GLsizei count, const GLvoid *values,
1082               struct gl_context *ctx, struct gl_shader_program *shProg,
1083               enum glsl_base_type basicType, unsigned src_components)
1084 {
1085    unsigned offset;
1086    int size_mul = glsl_base_type_is_64bit(basicType) ? 2 : 1;
1087 
1088    struct gl_uniform_storage *uni;
1089    if (_mesa_is_no_error_enabled(ctx)) {
1090       /* From Seciton 7.6 (UNIFORM VARIABLES) of the OpenGL 4.5 spec:
1091        *
1092        *   "If the value of location is -1, the Uniform* commands will
1093        *   silently ignore the data passed in, and the current uniform values
1094        *   will not be changed.
1095        */
1096       if (location == -1)
1097          return;
1098 
1099       uni = shProg->UniformRemapTable[location];
1100 
1101       /* The array index specified by the uniform location is just the
1102        * uniform location minus the base location of of the uniform.
1103        */
1104       assert(uni->array_elements > 0 || location == (int)uni->remap_location);
1105       offset = location - uni->remap_location;
1106    } else {
1107       uni = validate_uniform(location, count, values, &offset, ctx, shProg,
1108                              basicType, src_components);
1109       if (!uni)
1110          return;
1111    }
1112 
1113    const unsigned components = uni->type->vector_elements;
1114 
1115    /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
1116     *
1117     *     "When loading N elements starting at an arbitrary position k in a
1118     *     uniform declared as an array, elements k through k + N - 1 in the
1119     *     array will be replaced with the new values. Values for any array
1120     *     element that exceeds the highest array element index used, as
1121     *     reported by GetActiveUniform, will be ignored by the GL."
1122     *
1123     * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
1124     * will have already generated an error.
1125     */
1126    if (uni->array_elements != 0) {
1127       count = MIN2(count, (int) (uni->array_elements - offset));
1128    }
1129 
1130    /* We check samplers for changes and flush if needed in the sampler
1131     * handling code further down, so just skip them here.
1132     */
1133    if (!uni->type->is_sampler()) {
1134        _mesa_flush_vertices_for_uniforms(ctx, uni);
1135    }
1136 
1137    /* Store the data in the "actual type" backing storage for the uniform.
1138     */
1139    gl_constant_value *storage;
1140    if (ctx->Const.PackedDriverUniformStorage &&
1141        (uni->is_bindless || !uni->type->contains_opaque())) {
1142       for (unsigned s = 0; s < uni->num_driver_storage; s++) {
1143          storage = (gl_constant_value *)
1144             uni->driver_storage[s].data + (size_mul * offset * components);
1145 
1146          copy_uniforms_to_storage(storage, uni, ctx, count, values, size_mul,
1147                                   offset, components, basicType);
1148       }
1149    } else {
1150       storage = &uni->storage[size_mul * components * offset];
1151       copy_uniforms_to_storage(storage, uni, ctx, count, values, size_mul,
1152                                offset, components, basicType);
1153 
1154       _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
1155    }
1156 
1157    /* If the uniform is a sampler, do the extra magic necessary to propagate
1158     * the changes through.
1159     */
1160    if (uni->type->is_sampler()) {
1161       bool flushed = false;
1162 
1163       shProg->SamplersValidated = GL_TRUE;
1164 
1165       for (int i = 0; i < MESA_SHADER_STAGES; i++) {
1166          struct gl_linked_shader *const sh = shProg->_LinkedShaders[i];
1167 
1168          /* If the shader stage doesn't use the sampler uniform, skip this. */
1169          if (!uni->opaque[i].active)
1170             continue;
1171 
1172          bool changed = false;
1173          for (int j = 0; j < count; j++) {
1174             unsigned unit = uni->opaque[i].index + offset + j;
1175             unsigned value = ((unsigned *)values)[j];
1176 
1177             if (uni->is_bindless) {
1178                struct gl_bindless_sampler *sampler =
1179                   &sh->Program->sh.BindlessSamplers[unit];
1180 
1181                /* Mark this bindless sampler as bound to a texture unit.
1182                 */
1183                if (sampler->unit != value || !sampler->bound) {
1184                   if (!flushed) {
1185                      FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT | _NEW_PROGRAM);
1186                      flushed = true;
1187                   }
1188                   sampler->unit = value;
1189                   changed = true;
1190                }
1191                sampler->bound = true;
1192                sh->Program->sh.HasBoundBindlessSampler = true;
1193             } else {
1194                if (sh->Program->SamplerUnits[unit] != value) {
1195                   if (!flushed) {
1196                      FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT | _NEW_PROGRAM);
1197                      flushed = true;
1198                   }
1199                   sh->Program->SamplerUnits[unit] = value;
1200                   changed = true;
1201                }
1202             }
1203          }
1204 
1205          if (changed) {
1206             struct gl_program *const prog = sh->Program;
1207             _mesa_update_shader_textures_used(shProg, prog);
1208             if (ctx->Driver.SamplerUniformChange)
1209                ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog);
1210          }
1211       }
1212    }
1213 
1214    /* If the uniform is an image, update the mapping from image
1215     * uniforms to image units present in the shader data structure.
1216     */
1217    if (uni->type->is_image()) {
1218       for (int i = 0; i < MESA_SHADER_STAGES; i++) {
1219          struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
1220 
1221          /* If the shader stage doesn't use the image uniform, skip this. */
1222          if (!uni->opaque[i].active)
1223             continue;
1224 
1225          for (int j = 0; j < count; j++) {
1226             unsigned unit = uni->opaque[i].index + offset + j;
1227             unsigned value = ((unsigned *)values)[j];
1228 
1229             if (uni->is_bindless) {
1230                struct gl_bindless_image *image =
1231                   &sh->Program->sh.BindlessImages[unit];
1232 
1233                /* Mark this bindless image as bound to an image unit.
1234                 */
1235                image->unit = value;
1236                image->bound = true;
1237                sh->Program->sh.HasBoundBindlessImage = true;
1238             } else {
1239                sh->Program->sh.ImageUnits[unit] = value;
1240             }
1241          }
1242       }
1243 
1244       ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;
1245    }
1246 }
1247 
1248 
1249 static void
copy_uniform_matrix_to_storage(gl_constant_value * storage,GLsizei 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)1250 copy_uniform_matrix_to_storage(gl_constant_value *storage,
1251                                GLsizei count, const void *values,
1252                                const unsigned size_mul, const unsigned offset,
1253                                const unsigned components,
1254                                const unsigned vectors, bool transpose,
1255                                unsigned cols, unsigned rows,
1256                                enum glsl_base_type basicType)
1257 {
1258    const unsigned elements = components * vectors;
1259 
1260    if (!transpose) {
1261       memcpy(storage, values,
1262              sizeof(storage[0]) * elements * count * size_mul);
1263    } else if (basicType == GLSL_TYPE_FLOAT) {
1264       /* Copy and transpose the matrix.
1265        */
1266       const float *src = (const float *)values;
1267       float *dst = &storage->f;
1268 
1269       for (int i = 0; i < count; i++) {
1270          for (unsigned r = 0; r < rows; r++) {
1271             for (unsigned c = 0; c < cols; c++) {
1272                dst[(c * components) + r] = src[c + (r * vectors)];
1273             }
1274          }
1275 
1276          dst += elements;
1277          src += elements;
1278       }
1279    } else {
1280       assert(basicType == GLSL_TYPE_DOUBLE);
1281       const double *src = (const double *)values;
1282       double *dst = (double *)&storage->f;
1283 
1284       for (int i = 0; i < count; i++) {
1285          for (unsigned r = 0; r < rows; r++) {
1286             for (unsigned c = 0; c < cols; c++) {
1287                dst[(c * components) + r] = src[c + (r * vectors)];
1288             }
1289          }
1290 
1291          dst += elements;
1292          src += elements;
1293       }
1294    }
1295 }
1296 
1297 
1298 /**
1299  * Called by glUniformMatrix*() functions.
1300  * Note: cols=2, rows=4  ==>  array[2] of vec4
1301  */
1302 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)1303 _mesa_uniform_matrix(GLint location, GLsizei count,
1304                      GLboolean transpose, const void *values,
1305                      struct gl_context *ctx, struct gl_shader_program *shProg,
1306                      GLuint cols, GLuint rows, enum glsl_base_type basicType)
1307 {
1308    unsigned offset;
1309    struct gl_uniform_storage *const uni =
1310       validate_uniform_parameters(location, count, &offset,
1311                                   ctx, shProg, "glUniformMatrix");
1312    if (uni == NULL)
1313       return;
1314 
1315    if (!uni->type->is_matrix()) {
1316       _mesa_error(ctx, GL_INVALID_OPERATION,
1317 		  "glUniformMatrix(non-matrix uniform)");
1318       return;
1319    }
1320 
1321    assert(basicType == GLSL_TYPE_FLOAT || basicType == GLSL_TYPE_DOUBLE);
1322    const unsigned size_mul = basicType == GLSL_TYPE_DOUBLE ? 2 : 1;
1323 
1324    assert(!uni->type->is_sampler());
1325    const unsigned vectors = uni->type->matrix_columns;
1326    const unsigned components = uni->type->vector_elements;
1327 
1328    /* Verify that the types are compatible.  This is greatly simplified for
1329     * matrices because they can only have a float base type.
1330     */
1331    if (vectors != cols || components != rows) {
1332       _mesa_error(ctx, GL_INVALID_OPERATION,
1333 		  "glUniformMatrix(matrix size mismatch)");
1334       return;
1335    }
1336 
1337    /* GL_INVALID_VALUE is generated if `transpose' is not GL_FALSE.
1338     * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml
1339     */
1340    if (transpose) {
1341       if (ctx->API == API_OPENGLES2 && ctx->Version < 30) {
1342 	 _mesa_error(ctx, GL_INVALID_VALUE,
1343 		     "glUniformMatrix(matrix transpose is not GL_FALSE)");
1344 	 return;
1345       }
1346    }
1347 
1348    /* Section 2.11.7 (Uniform Variables) of the OpenGL 4.2 Core Profile spec
1349     * says:
1350     *
1351     *     "If any of the following conditions occur, an INVALID_OPERATION
1352     *     error is generated by the Uniform* commands, and no uniform values
1353     *     are changed:
1354     *
1355     *     ...
1356     *
1357     *     - if the uniform declared in the shader is not of type boolean and
1358     *       the type indicated in the name of the Uniform* command used does
1359     *       not match the type of the uniform"
1360     *
1361     * There are no Boolean matrix types, so we do not need to allow
1362     * GLSL_TYPE_BOOL here (as _mesa_uniform does).
1363     */
1364    if (uni->type->base_type != basicType) {
1365       _mesa_error(ctx, GL_INVALID_OPERATION,
1366                   "glUniformMatrix%ux%u(\"%s\"@%d is %s, not %s)",
1367                   cols, rows, uni->name, location,
1368                   glsl_type_name(uni->type->base_type),
1369                   glsl_type_name(basicType));
1370       return;
1371    }
1372 
1373    if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
1374       log_uniform(values, uni->type->base_type, components, vectors, count,
1375 		  bool(transpose), shProg, location, uni);
1376    }
1377 
1378    /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
1379     *
1380     *     "When loading N elements starting at an arbitrary position k in a
1381     *     uniform declared as an array, elements k through k + N - 1 in the
1382     *     array will be replaced with the new values. Values for any array
1383     *     element that exceeds the highest array element index used, as
1384     *     reported by GetActiveUniform, will be ignored by the GL."
1385     *
1386     * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
1387     * will have already generated an error.
1388     */
1389    if (uni->array_elements != 0) {
1390       count = MIN2(count, (int) (uni->array_elements - offset));
1391    }
1392 
1393    _mesa_flush_vertices_for_uniforms(ctx, uni);
1394 
1395    /* Store the data in the "actual type" backing storage for the uniform.
1396     */
1397    gl_constant_value *storage;
1398    const unsigned elements = components * vectors;
1399    if (ctx->Const.PackedDriverUniformStorage) {
1400       for (unsigned s = 0; s < uni->num_driver_storage; s++) {
1401          storage = (gl_constant_value *)
1402             uni->driver_storage[s].data + (size_mul * offset * elements);
1403 
1404          copy_uniform_matrix_to_storage(storage, count, values, size_mul,
1405                                         offset, components, vectors,
1406                                         transpose, cols, rows, basicType);
1407       }
1408    } else {
1409       storage =  &uni->storage[size_mul * elements * offset];
1410       copy_uniform_matrix_to_storage(storage, count, values, size_mul, offset,
1411                                      components, vectors, transpose, cols,
1412                                      rows, basicType);
1413 
1414       _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
1415    }
1416 }
1417 
1418 static void
update_bound_bindless_sampler_flag(struct gl_program * prog)1419 update_bound_bindless_sampler_flag(struct gl_program *prog)
1420 {
1421    unsigned i;
1422 
1423    if (likely(!prog->sh.HasBoundBindlessSampler))
1424       return;
1425 
1426    for (i = 0; i < prog->sh.NumBindlessSamplers; i++) {
1427       struct gl_bindless_sampler *sampler = &prog->sh.BindlessSamplers[i];
1428 
1429       if (sampler->bound)
1430          return;
1431    }
1432    prog->sh.HasBoundBindlessSampler = false;
1433 }
1434 
1435 static void
update_bound_bindless_image_flag(struct gl_program * prog)1436 update_bound_bindless_image_flag(struct gl_program *prog)
1437 {
1438    unsigned i;
1439 
1440    if (likely(!prog->sh.HasBoundBindlessImage))
1441       return;
1442 
1443    for (i = 0; i < prog->sh.NumBindlessImages; i++) {
1444       struct gl_bindless_image *image = &prog->sh.BindlessImages[i];
1445 
1446       if (image->bound)
1447          return;
1448    }
1449    prog->sh.HasBoundBindlessImage = false;
1450 }
1451 
1452 /**
1453  * Called via glUniformHandleui64*ARB() functions.
1454  */
1455 extern "C" void
_mesa_uniform_handle(GLint location,GLsizei count,const GLvoid * values,struct gl_context * ctx,struct gl_shader_program * shProg)1456 _mesa_uniform_handle(GLint location, GLsizei count, const GLvoid *values,
1457                      struct gl_context *ctx, struct gl_shader_program *shProg)
1458 {
1459    unsigned offset;
1460    struct gl_uniform_storage *uni;
1461 
1462    if (_mesa_is_no_error_enabled(ctx)) {
1463       /* From Section 7.6 (UNIFORM VARIABLES) of the OpenGL 4.5 spec:
1464        *
1465        *   "If the value of location is -1, the Uniform* commands will
1466        *   silently ignore the data passed in, and the current uniform values
1467        *   will not be changed.
1468        */
1469       if (location == -1)
1470          return;
1471 
1472       uni = shProg->UniformRemapTable[location];
1473 
1474       /* The array index specified by the uniform location is just the
1475        * uniform location minus the base location of of the uniform.
1476        */
1477       assert(uni->array_elements > 0 || location == (int)uni->remap_location);
1478       offset = location - uni->remap_location;
1479    } else {
1480       uni = validate_uniform_parameters(location, count, &offset,
1481                                         ctx, shProg, "glUniformHandleui64*ARB");
1482       if (!uni)
1483          return;
1484 
1485       if (!uni->is_bindless) {
1486          /* From section "Errors" of the ARB_bindless_texture spec:
1487           *
1488           * "The error INVALID_OPERATION is generated by
1489           *  UniformHandleui64{v}ARB if the sampler or image uniform being
1490           *  updated has the "bound_sampler" or "bound_image" layout qualifier."
1491           *
1492           * From section 4.4.6 of the ARB_bindless_texture spec:
1493           *
1494           * "In the absence of these qualifiers, sampler and image uniforms are
1495           *  considered "bound". Additionally, if GL_ARB_bindless_texture is
1496           *  not enabled, these uniforms are considered "bound"."
1497           */
1498          _mesa_error(ctx, GL_INVALID_OPERATION,
1499                      "glUniformHandleui64*ARB(non-bindless sampler/image uniform)");
1500          return;
1501       }
1502    }
1503 
1504    const unsigned components = uni->type->vector_elements;
1505    const int size_mul = 2;
1506 
1507    if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
1508       log_uniform(values, GLSL_TYPE_UINT64, components, 1, count,
1509                   false, shProg, location, uni);
1510    }
1511 
1512    /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
1513     *
1514     *     "When loading N elements starting at an arbitrary position k in a
1515     *     uniform declared as an array, elements k through k + N - 1 in the
1516     *     array will be replaced with the new values. Values for any array
1517     *     element that exceeds the highest array element index used, as
1518     *     reported by GetActiveUniform, will be ignored by the GL."
1519     *
1520     * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
1521     * will have already generated an error.
1522     */
1523    if (uni->array_elements != 0) {
1524       count = MIN2(count, (int) (uni->array_elements - offset));
1525    }
1526 
1527    _mesa_flush_vertices_for_uniforms(ctx, uni);
1528 
1529    /* Store the data in the "actual type" backing storage for the uniform.
1530     */
1531    gl_constant_value *storage;
1532    if (ctx->Const.PackedDriverUniformStorage) {
1533       for (unsigned s = 0; s < uni->num_driver_storage; s++) {
1534          storage = (gl_constant_value *)
1535             uni->driver_storage[s].data + (size_mul * offset * components);
1536          memcpy(storage, values,
1537                 sizeof(uni->storage[0]) * components * count * size_mul);
1538       }
1539    } else {
1540       memcpy(&uni->storage[size_mul * components * offset], values,
1541              sizeof(uni->storage[0]) * components * count * size_mul);
1542 
1543       _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
1544    }
1545 
1546    if (uni->type->is_sampler()) {
1547       /* Mark this bindless sampler as not bound to a texture unit because
1548        * it refers to a texture handle.
1549        */
1550       for (int i = 0; i < MESA_SHADER_STAGES; i++) {
1551          struct gl_linked_shader *const sh = shProg->_LinkedShaders[i];
1552 
1553          /* If the shader stage doesn't use the sampler uniform, skip this. */
1554          if (!uni->opaque[i].active)
1555             continue;
1556 
1557          for (int j = 0; j < count; j++) {
1558             unsigned unit = uni->opaque[i].index + offset + j;
1559             struct gl_bindless_sampler *sampler =
1560                &sh->Program->sh.BindlessSamplers[unit];
1561 
1562             sampler->bound = false;
1563          }
1564 
1565          update_bound_bindless_sampler_flag(sh->Program);
1566       }
1567    }
1568 
1569    if (uni->type->is_image()) {
1570       /* Mark this bindless image as not bound to an image unit because it
1571        * refers to a texture handle.
1572        */
1573       for (int i = 0; i < MESA_SHADER_STAGES; i++) {
1574          struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
1575 
1576          /* If the shader stage doesn't use the sampler uniform, skip this. */
1577          if (!uni->opaque[i].active)
1578             continue;
1579 
1580          for (int j = 0; j < count; j++) {
1581             unsigned unit = uni->opaque[i].index + offset + j;
1582             struct gl_bindless_image *image =
1583                &sh->Program->sh.BindlessImages[unit];
1584 
1585             image->bound = false;
1586          }
1587 
1588          update_bound_bindless_image_flag(sh->Program);
1589       }
1590    }
1591 }
1592 
1593 extern "C" bool
_mesa_sampler_uniforms_are_valid(const struct gl_shader_program * shProg,char * errMsg,size_t errMsgLength)1594 _mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
1595 				 char *errMsg, size_t errMsgLength)
1596 {
1597    /* Shader does not have samplers. */
1598    if (shProg->data->NumUniformStorage == 0)
1599       return true;
1600 
1601    if (!shProg->SamplersValidated) {
1602       snprintf(errMsg, errMsgLength,
1603                      "active samplers with a different type "
1604                      "refer to the same texture image unit");
1605       return false;
1606    }
1607    return true;
1608 }
1609 
1610 extern "C" bool
_mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object * pipeline)1611 _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline)
1612 {
1613    /* Section 2.11.11 (Shader Execution), subheading "Validation," of the
1614     * OpenGL 4.1 spec says:
1615     *
1616     *     "[INVALID_OPERATION] is generated by any command that transfers
1617     *     vertices to the GL if:
1618     *
1619     *         ...
1620     *
1621     *         - Any two active samplers in the current program object are of
1622     *           different types, but refer to the same texture image unit.
1623     *
1624     *         - The number of active samplers in the program exceeds the
1625     *           maximum number of texture image units allowed."
1626     */
1627 
1628    GLbitfield mask;
1629    GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
1630    unsigned active_samplers = 0;
1631    const struct gl_program **prog =
1632       (const struct gl_program **) pipeline->CurrentProgram;
1633 
1634 
1635    memset(TexturesUsed, 0, sizeof(TexturesUsed));
1636 
1637    for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
1638       if (!prog[idx])
1639          continue;
1640 
1641       mask = prog[idx]->SamplersUsed;
1642       while (mask) {
1643          const int s = u_bit_scan(&mask);
1644          GLuint unit = prog[idx]->SamplerUnits[s];
1645          GLuint tgt = prog[idx]->sh.SamplerTargets[s];
1646 
1647          /* FIXME: Samplers are initialized to 0 and Mesa doesn't do a
1648           * great job of eliminating unused uniforms currently so for now
1649           * don't throw an error if two sampler types both point to 0.
1650           */
1651          if (unit == 0)
1652             continue;
1653 
1654          if (TexturesUsed[unit] & ~(1 << tgt)) {
1655             pipeline->InfoLog =
1656                ralloc_asprintf(pipeline,
1657                      "Program %d: "
1658                      "Texture unit %d is accessed with 2 different types",
1659                      prog[idx]->Id, unit);
1660             return false;
1661          }
1662 
1663          TexturesUsed[unit] |= (1 << tgt);
1664       }
1665 
1666       active_samplers += prog[idx]->info.num_textures;
1667    }
1668 
1669    if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) {
1670       pipeline->InfoLog =
1671          ralloc_asprintf(pipeline,
1672                          "the number of active samplers %d exceed the "
1673                          "maximum %d",
1674                          active_samplers, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
1675       return false;
1676    }
1677 
1678    return true;
1679 }
1680