• 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 
29 #include "main/core.h"
30 #include "main/context.h"
31 #include "main/shaderapi.h"
32 #include "main/shaderobj.h"
33 #include "main/uniforms.h"
34 #include "compiler/glsl/ir.h"
35 #include "compiler/glsl/ir_uniform.h"
36 #include "compiler/glsl/glsl_parser_extras.h"
37 #include "compiler/glsl/program.h"
38 #include "util/bitscan.h"
39 
40 
41 extern "C" void GLAPIENTRY
_mesa_GetActiveUniform(GLuint program,GLuint index,GLsizei maxLength,GLsizei * length,GLint * size,GLenum * type,GLcharARB * nameOut)42 _mesa_GetActiveUniform(GLuint program, GLuint index,
43                        GLsizei maxLength, GLsizei *length, GLint *size,
44                        GLenum *type, GLcharARB *nameOut)
45 {
46    GET_CURRENT_CONTEXT(ctx);
47    struct gl_shader_program *shProg;
48    struct gl_program_resource *res;
49 
50    if (maxLength < 0) {
51       _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(maxLength < 0)");
52       return;
53    }
54 
55    shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
56    if (!shProg)
57       return;
58 
59    res = _mesa_program_resource_find_index((struct gl_shader_program *) shProg,
60                                            GL_UNIFORM, index);
61 
62    if (!res) {
63       _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
64       return;
65    }
66 
67    if (nameOut)
68       _mesa_get_program_resource_name(shProg, GL_UNIFORM, index, maxLength,
69                                       length, nameOut, "glGetActiveUniform");
70    if (type)
71       _mesa_program_resource_prop((struct gl_shader_program *) shProg,
72                                   res, index, GL_TYPE, (GLint*) type,
73                                   "glGetActiveUniform");
74    if (size)
75       _mesa_program_resource_prop((struct gl_shader_program *) shProg,
76                                   res, index, GL_ARRAY_SIZE, (GLint*) size,
77                                   "glGetActiveUniform");
78 }
79 
80 static GLenum
resource_prop_from_uniform_prop(GLenum uni_prop)81 resource_prop_from_uniform_prop(GLenum uni_prop)
82 {
83    switch (uni_prop) {
84    case GL_UNIFORM_TYPE:
85       return GL_TYPE;
86    case GL_UNIFORM_SIZE:
87       return GL_ARRAY_SIZE;
88    case GL_UNIFORM_NAME_LENGTH:
89       return GL_NAME_LENGTH;
90    case GL_UNIFORM_BLOCK_INDEX:
91       return GL_BLOCK_INDEX;
92    case GL_UNIFORM_OFFSET:
93       return GL_OFFSET;
94    case GL_UNIFORM_ARRAY_STRIDE:
95       return GL_ARRAY_STRIDE;
96    case GL_UNIFORM_MATRIX_STRIDE:
97       return GL_MATRIX_STRIDE;
98    case GL_UNIFORM_IS_ROW_MAJOR:
99       return GL_IS_ROW_MAJOR;
100    case GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX:
101       return GL_ATOMIC_COUNTER_BUFFER_INDEX;
102    default:
103       return 0;
104    }
105 }
106 
107 extern "C" void GLAPIENTRY
_mesa_GetActiveUniformsiv(GLuint program,GLsizei uniformCount,const GLuint * uniformIndices,GLenum pname,GLint * params)108 _mesa_GetActiveUniformsiv(GLuint program,
109 			  GLsizei uniformCount,
110 			  const GLuint *uniformIndices,
111 			  GLenum pname,
112 			  GLint *params)
113 {
114    GET_CURRENT_CONTEXT(ctx);
115    struct gl_shader_program *shProg;
116    struct gl_program_resource *res;
117    GLenum res_prop;
118 
119    if (uniformCount < 0) {
120       _mesa_error(ctx, GL_INVALID_VALUE,
121 		  "glGetActiveUniformsiv(uniformCount < 0)");
122       return;
123    }
124 
125    shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
126    if (!shProg)
127       return;
128 
129    res_prop = resource_prop_from_uniform_prop(pname);
130 
131    /* We need to first verify that each entry exists as active uniform. If
132     * not, generate error and do not cause any other side effects.
133     *
134     * In the case of and error condition, Page 16 (section 2.3.1 Errors)
135     * of the OpenGL 4.5 spec says:
136     *
137     *     "If the generating command modifies values through a pointer argu-
138     *     ment, no change is made to these values."
139     */
140    for (int i = 0; i < uniformCount; i++) {
141       if (!_mesa_program_resource_find_index(shProg, GL_UNIFORM,
142                                               uniformIndices[i])) {
143          _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)");
144          return;
145       }
146    }
147 
148    for (int i = 0; i < uniformCount; i++) {
149       res = _mesa_program_resource_find_index(shProg, GL_UNIFORM,
150                                               uniformIndices[i]);
151       if (!_mesa_program_resource_prop(shProg, res, uniformIndices[i],
152                                        res_prop, &params[i],
153                                        "glGetActiveUniformsiv"))
154          break;
155    }
156 }
157 
158 static struct gl_uniform_storage *
validate_uniform_parameters(struct gl_context * ctx,struct gl_shader_program * shProg,GLint location,GLsizei count,unsigned * array_index,const char * caller)159 validate_uniform_parameters(struct gl_context *ctx,
160 			    struct gl_shader_program *shProg,
161 			    GLint location, GLsizei count,
162 			    unsigned *array_index,
163 			    const char *caller)
164 {
165    if (shProg == NULL) {
166       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", caller);
167       return NULL;
168    }
169 
170    /* From page 12 (page 26 of the PDF) of the OpenGL 2.1 spec:
171     *
172     *     "If a negative number is provided where an argument of type sizei or
173     *     sizeiptr is specified, the error INVALID_VALUE is generated."
174     */
175    if (count < 0) {
176       _mesa_error(ctx, GL_INVALID_VALUE, "%s(count < 0)", caller);
177       return NULL;
178    }
179 
180    /* Check that the given location is in bounds of uniform remap table.
181     * Unlinked programs will have NumUniformRemapTable == 0, so we can take
182     * the shProg->data->LinkStatus check out of the main path.
183     */
184    if (unlikely(location >= (GLint) shProg->NumUniformRemapTable)) {
185       if (!shProg->data->LinkStatus)
186          _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)",
187                      caller);
188       else
189          _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
190                      caller, location);
191 
192       return NULL;
193    }
194 
195    if (location == -1) {
196       if (!shProg->data->LinkStatus)
197          _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)",
198                      caller);
199 
200       return NULL;
201    }
202 
203    /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
204     *
205     *     "If any of the following conditions occur, an INVALID_OPERATION
206     *     error is generated by the Uniform* commands, and no uniform values
207     *     are changed:
208     *
209     *     ...
210     *
211     *         - if no variable with a location of location exists in the
212     *           program object currently in use and location is not -1,
213     *         - if count is greater than one, and the uniform declared in the
214     *           shader is not an array variable,
215     */
216    if (location < -1 || !shProg->UniformRemapTable[location]) {
217       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
218                   caller, location);
219       return NULL;
220    }
221 
222    /* If the driver storage pointer in remap table is -1, we ignore silently.
223     *
224     * GL_ARB_explicit_uniform_location spec says:
225     *     "What happens if Uniform* is called with an explicitly defined
226     *     uniform location, but that uniform is deemed inactive by the
227     *     linker?
228     *
229     *     RESOLVED: The call is ignored for inactive uniform variables and
230     *     no error is generated."
231     *
232     */
233    if (shProg->UniformRemapTable[location] ==
234        INACTIVE_UNIFORM_EXPLICIT_LOCATION)
235       return NULL;
236 
237    struct gl_uniform_storage *const uni = shProg->UniformRemapTable[location];
238 
239    /* Even though no location is assigned to a built-in uniform and this
240     * function should already have returned NULL, this test makes it explicit
241     * that we are not allowing to update the value of a built-in.
242     */
243    if (uni->builtin)
244       return NULL;
245 
246    if (uni->array_elements == 0) {
247       if (count > 1) {
248          _mesa_error(ctx, GL_INVALID_OPERATION,
249                      "%s(count = %u for non-array \"%s\"@%d)",
250                      caller, count, uni->name, location);
251          return NULL;
252       }
253 
254       assert((location - uni->remap_location) == 0);
255       *array_index = 0;
256    } else {
257       /* The array index specified by the uniform location is just the uniform
258        * location minus the base location of of the uniform.
259        */
260       *array_index = location - uni->remap_location;
261 
262       /* If the uniform is an array, check that array_index is in bounds.
263        * array_index is unsigned so no need to check for less than zero.
264        */
265       if (*array_index >= uni->array_elements) {
266          _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
267                      caller, location);
268          return NULL;
269       }
270    }
271    return uni;
272 }
273 
274 /**
275  * Called via glGetUniform[fiui]v() to get the current value of a uniform.
276  */
277 extern "C" void
_mesa_get_uniform(struct gl_context * ctx,GLuint program,GLint location,GLsizei bufSize,enum glsl_base_type returnType,GLvoid * paramsOut)278 _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
279 		  GLsizei bufSize, enum glsl_base_type returnType,
280 		  GLvoid *paramsOut)
281 {
282    struct gl_shader_program *shProg =
283       _mesa_lookup_shader_program_err(ctx, program, "glGetUniformfv");
284    unsigned offset;
285 
286    struct gl_uniform_storage *const uni =
287       validate_uniform_parameters(ctx, shProg, location, 1,
288                                   &offset, "glGetUniform");
289    if (uni == NULL) {
290       /* For glGetUniform, page 264 (page 278 of the PDF) of the OpenGL 2.1
291        * spec says:
292        *
293        *     "The error INVALID_OPERATION is generated if program has not been
294        *     linked successfully, or if location is not a valid location for
295        *     program."
296        *
297        * For glUniform, page 82 (page 96 of the PDF) of the OpenGL 2.1 spec
298        * says:
299        *
300        *     "If the value of location is -1, the Uniform* commands will
301        *     silently ignore the data passed in, and the current uniform
302        *     values will not be changed."
303        *
304        * Allowing -1 for the location parameter of glUniform allows
305        * applications to avoid error paths in the case that, for example, some
306        * uniform variable is removed by the compiler / linker after
307        * optimization.  In this case, the new value of the uniform is dropped
308        * on the floor.  For the case of glGetUniform, there is nothing
309        * sensible to do for a location of -1.
310        *
311        * If the location was -1, validate_unfirom_parameters will return NULL
312        * without raising an error.  Raise the error here.
313        */
314       if (location == -1) {
315          _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniform(location=%d)",
316                      location);
317       }
318 
319       return;
320    }
321 
322    {
323       unsigned elements = (uni->type->is_sampler())
324 	 ? 1 : uni->type->components();
325       const int dmul = uni->type->is_64bit() ? 2 : 1;
326       const int rmul = glsl_base_type_is_64bit(returnType) ? 2 : 1;
327 
328       /* Calculate the source base address *BEFORE* modifying elements to
329        * account for the size of the user's buffer.
330        */
331       const union gl_constant_value *const src =
332 	 &uni->storage[offset * elements * dmul];
333 
334       assert(returnType == GLSL_TYPE_FLOAT || returnType == GLSL_TYPE_INT ||
335              returnType == GLSL_TYPE_UINT || returnType == GLSL_TYPE_DOUBLE);
336 
337       /* doubles have a different size than the other 3 types */
338       unsigned bytes = sizeof(src[0]) * elements * rmul;
339       if (bufSize < 0 || bytes > (unsigned) bufSize) {
340 	 _mesa_error( ctx, GL_INVALID_OPERATION,
341 	             "glGetnUniform*vARB(out of bounds: bufSize is %d,"
342 	             " but %u bytes are required)", bufSize, bytes );
343 	 return;
344       }
345 
346       /* If the return type and the uniform's native type are "compatible,"
347        * just memcpy the data.  If the types are not compatible, perform a
348        * slower convert-and-copy process.
349        */
350       if (returnType == uni->type->base_type
351 	  || ((returnType == GLSL_TYPE_INT
352 	       || returnType == GLSL_TYPE_UINT)
353 	      &&
354 	      (uni->type->base_type == GLSL_TYPE_INT
355 	       || uni->type->base_type == GLSL_TYPE_UINT
356                || uni->type->base_type == GLSL_TYPE_SAMPLER
357                || uni->type->base_type == GLSL_TYPE_IMAGE))) {
358 	 memcpy(paramsOut, src, bytes);
359       } else {
360 	 union gl_constant_value *const dst =
361 	    (union gl_constant_value *) paramsOut;
362 	 /* This code could be optimized by putting the loop inside the switch
363 	  * statements.  However, this is not expected to be
364 	  * performance-critical code.
365 	  */
366 	 for (unsigned i = 0; i < elements; i++) {
367 	   int sidx = i * dmul;
368 	   int didx = i * rmul;
369 
370 	    switch (returnType) {
371 	    case GLSL_TYPE_FLOAT:
372 	       switch (uni->type->base_type) {
373 	       case GLSL_TYPE_UINT:
374 		  dst[didx].f = (float) src[sidx].u;
375 		  break;
376 	       case GLSL_TYPE_INT:
377 	       case GLSL_TYPE_SAMPLER:
378                case GLSL_TYPE_IMAGE:
379 		  dst[didx].f = (float) src[sidx].i;
380 		  break;
381 	       case GLSL_TYPE_BOOL:
382 		  dst[didx].f = src[sidx].i ? 1.0f : 0.0f;
383 		  break;
384                case GLSL_TYPE_DOUBLE: {
385                   double tmp;
386                   memcpy(&tmp, &src[sidx].f, sizeof(tmp));
387                   dst[didx].f = tmp;
388 		  break;
389                }
390 	       default:
391 		  assert(!"Should not get here.");
392 		  break;
393 	       }
394 	       break;
395 	    case GLSL_TYPE_DOUBLE:
396 	       switch (uni->type->base_type) {
397                case GLSL_TYPE_UINT: {
398                   double tmp = src[sidx].u;
399                   memcpy(&dst[didx].f, &tmp, sizeof(tmp));
400 		  break;
401                }
402 	       case GLSL_TYPE_INT:
403 	       case GLSL_TYPE_SAMPLER:
404                case GLSL_TYPE_IMAGE: {
405                   double tmp = src[sidx].i;
406                   memcpy(&dst[didx].f, &tmp, sizeof(tmp));
407 		  break;
408                }
409                case GLSL_TYPE_BOOL: {
410                   double tmp = src[sidx].i ? 1.0 : 0.0;
411                   memcpy(&dst[didx].f, &tmp, sizeof(tmp));
412 		  break;
413                }
414                case GLSL_TYPE_FLOAT: {
415                   double tmp = src[sidx].f;
416                   memcpy(&dst[didx].f, &tmp, sizeof(tmp));
417 		  break;
418                }
419 	       default:
420 		  assert(!"Should not get here.");
421 		  break;
422 	       }
423 	       break;
424 	    case GLSL_TYPE_INT:
425 	    case GLSL_TYPE_UINT:
426 	       switch (uni->type->base_type) {
427 	       case GLSL_TYPE_FLOAT:
428 		  /* While the GL 3.2 core spec doesn't explicitly
429 		   * state how conversion of float uniforms to integer
430 		   * values works, in section 6.2 "State Tables" on
431 		   * page 267 it says:
432 		   *
433 		   *     "Unless otherwise specified, when floating
434 		   *      point state is returned as integer values or
435 		   *      integer state is returned as floating-point
436 		   *      values it is converted in the fashion
437 		   *      described in section 6.1.2"
438 		   *
439 		   * That section, on page 248, says:
440 		   *
441 		   *     "If GetIntegerv or GetInteger64v are called,
442 		   *      a floating-point value is rounded to the
443 		   *      nearest integer..."
444 		   */
445 		  dst[didx].i = IROUND(src[sidx].f);
446 		  break;
447 	       case GLSL_TYPE_BOOL:
448 		  dst[didx].i = src[sidx].i ? 1 : 0;
449 		  break;
450                case GLSL_TYPE_DOUBLE: {
451                   double tmp;
452                   memcpy(&tmp, &src[sidx].f, sizeof(tmp));
453                   dst[didx].i = IROUNDD(tmp);
454 		  break;
455                }
456 	       default:
457 		  assert(!"Should not get here.");
458 		  break;
459 	       }
460 	       break;
461 
462 	    default:
463 	       assert(!"Should not get here.");
464 	       break;
465 	    }
466 	 }
467       }
468    }
469 }
470 
471 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)472 log_uniform(const void *values, enum glsl_base_type basicType,
473 	    unsigned rows, unsigned cols, unsigned count,
474 	    bool transpose,
475 	    const struct gl_shader_program *shProg,
476 	    GLint location,
477 	    const struct gl_uniform_storage *uni)
478 {
479 
480    const union gl_constant_value *v = (const union gl_constant_value *) values;
481    const unsigned elems = rows * cols * count;
482    const char *const extra = (cols == 1) ? "uniform" : "uniform matrix";
483 
484    printf("Mesa: set program %u %s \"%s\" (loc %d, type \"%s\", "
485 	  "transpose = %s) to: ",
486 	  shProg->Name, extra, uni->name, location, uni->type->name,
487 	  transpose ? "true" : "false");
488    for (unsigned i = 0; i < elems; i++) {
489       if (i != 0 && ((i % rows) == 0))
490 	 printf(", ");
491 
492       switch (basicType) {
493       case GLSL_TYPE_UINT:
494 	 printf("%u ", v[i].u);
495 	 break;
496       case GLSL_TYPE_INT:
497 	 printf("%d ", v[i].i);
498 	 break;
499       case GLSL_TYPE_FLOAT:
500 	 printf("%g ", v[i].f);
501 	 break;
502       case GLSL_TYPE_DOUBLE: {
503          double tmp;
504          memcpy(&tmp, &v[i * 2].f, sizeof(tmp));
505          printf("%g ", tmp);
506          break;
507       }
508       default:
509 	 assert(!"Should not get here.");
510 	 break;
511       }
512    }
513    printf("\n");
514    fflush(stdout);
515 }
516 
517 #if 0
518 static void
519 log_program_parameters(const struct gl_shader_program *shProg)
520 {
521    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
522       if (shProg->_LinkedShaders[i] == NULL)
523 	 continue;
524 
525       const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program;
526 
527       printf("Program %d %s shader parameters:\n",
528              shProg->Name, _mesa_shader_stage_to_string(i));
529       for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) {
530 	 printf("%s: %p %f %f %f %f\n",
531 		prog->Parameters->Parameters[j].Name,
532 		prog->Parameters->ParameterValues[j],
533 		prog->Parameters->ParameterValues[j][0].f,
534 		prog->Parameters->ParameterValues[j][1].f,
535 		prog->Parameters->ParameterValues[j][2].f,
536 		prog->Parameters->ParameterValues[j][3].f);
537       }
538    }
539    fflush(stdout);
540 }
541 #endif
542 
543 /**
544  * Propagate some values from uniform backing storage to driver storage
545  *
546  * Values propagated from uniform backing storage to driver storage
547  * have all format / type conversions previously requested by the
548  * driver applied.  This function is most often called by the
549  * implementations of \c glUniform1f, etc. and \c glUniformMatrix2f,
550  * etc.
551  *
552  * \param uni          Uniform whose data is to be propagated to driver storage
553  * \param array_index  If \c uni is an array, this is the element of
554  *                     the array to be propagated.
555  * \param count        Number of array elements to propagate.
556  */
557 extern "C" void
_mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage * uni,unsigned array_index,unsigned count)558 _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni,
559 					   unsigned array_index,
560 					   unsigned count)
561 {
562    unsigned i;
563 
564    /* vector_elements and matrix_columns can be 0 for samplers.
565     */
566    const unsigned components = MAX2(1, uni->type->vector_elements);
567    const unsigned vectors = MAX2(1, uni->type->matrix_columns);
568    const int dmul = uni->type->is_64bit() ? 2 : 1;
569 
570    /* Store the data in the driver's requested type in the driver's storage
571     * areas.
572     */
573    unsigned src_vector_byte_stride = components * 4 * dmul;
574 
575    for (i = 0; i < uni->num_driver_storage; i++) {
576       struct gl_uniform_driver_storage *const store = &uni->driver_storage[i];
577       uint8_t *dst = (uint8_t *) store->data;
578       const unsigned extra_stride =
579 	 store->element_stride - (vectors * store->vector_stride);
580       const uint8_t *src =
581 	 (uint8_t *) (&uni->storage[array_index * (dmul * components * vectors)].i);
582 
583 #if 0
584       printf("%s: %p[%d] components=%u vectors=%u count=%u vector_stride=%u "
585 	     "extra_stride=%u\n",
586 	     __func__, dst, array_index, components,
587 	     vectors, count, store->vector_stride, extra_stride);
588 #endif
589 
590       dst += array_index * store->element_stride;
591 
592       switch (store->format) {
593       case uniform_native: {
594 	 unsigned j;
595 	 unsigned v;
596 
597 	 if (src_vector_byte_stride == store->vector_stride) {
598 	    if (extra_stride) {
599 	       for (j = 0; j < count; j++) {
600 	          memcpy(dst, src, src_vector_byte_stride * vectors);
601 	          src += src_vector_byte_stride * vectors;
602 	          dst += store->vector_stride * vectors;
603 
604 	          dst += extra_stride;
605 	       }
606 	    } else {
607 	       /* Unigine Heaven benchmark gets here */
608 	       memcpy(dst, src, src_vector_byte_stride * vectors * count);
609 	       src += src_vector_byte_stride * vectors * count;
610 	       dst += store->vector_stride * vectors * count;
611 	    }
612 	 } else {
613 	    for (j = 0; j < count; j++) {
614 	       for (v = 0; v < vectors; v++) {
615 	          memcpy(dst, src, src_vector_byte_stride);
616 	          src += src_vector_byte_stride;
617 	          dst += store->vector_stride;
618 	       }
619 
620 	       dst += extra_stride;
621 	    }
622 	 }
623 	 break;
624       }
625 
626       case uniform_int_float: {
627 	 const int *isrc = (const int *) src;
628 	 unsigned j;
629 	 unsigned v;
630 	 unsigned c;
631 
632 	 for (j = 0; j < count; j++) {
633 	    for (v = 0; v < vectors; v++) {
634 	       for (c = 0; c < components; c++) {
635 		  ((float *) dst)[c] = (float) *isrc;
636 		  isrc++;
637 	       }
638 
639 	       dst += store->vector_stride;
640 	    }
641 
642 	    dst += extra_stride;
643 	 }
644 	 break;
645       }
646 
647       default:
648 	 assert(!"Should not get here.");
649 	 break;
650       }
651    }
652 }
653 
654 
655 /**
656  * Return printable string for a given GLSL_TYPE_x
657  */
658 static const char *
glsl_type_name(enum glsl_base_type type)659 glsl_type_name(enum glsl_base_type type)
660 {
661    switch (type) {
662    case GLSL_TYPE_UINT:
663       return "uint";
664    case GLSL_TYPE_INT:
665       return "int";
666    case GLSL_TYPE_FLOAT:
667       return "float";
668    case GLSL_TYPE_DOUBLE:
669       return "double";
670    case GLSL_TYPE_BOOL:
671       return "bool";
672    case GLSL_TYPE_SAMPLER:
673       return "sampler";
674    case GLSL_TYPE_IMAGE:
675       return "image";
676    case GLSL_TYPE_ATOMIC_UINT:
677       return "atomic_uint";
678    case GLSL_TYPE_STRUCT:
679       return "struct";
680    case GLSL_TYPE_INTERFACE:
681       return "interface";
682    case GLSL_TYPE_ARRAY:
683       return "array";
684    case GLSL_TYPE_VOID:
685       return "void";
686    case GLSL_TYPE_ERROR:
687       return "error";
688    default:
689       return "other";
690    }
691 }
692 
693 
694 /**
695  * Called via glUniform*() functions.
696  */
697 extern "C" void
_mesa_uniform(struct gl_context * ctx,struct gl_shader_program * shProg,GLint location,GLsizei count,const GLvoid * values,enum glsl_base_type basicType,unsigned src_components)698 _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
699 	      GLint location, GLsizei count,
700               const GLvoid *values,
701               enum glsl_base_type basicType,
702               unsigned src_components)
703 {
704    unsigned offset;
705    int size_mul = glsl_base_type_is_64bit(basicType) ? 2 : 1;
706 
707    struct gl_uniform_storage *const uni =
708       validate_uniform_parameters(ctx, shProg, location, count,
709                                   &offset, "glUniform");
710    if (uni == NULL)
711       return;
712 
713    if (uni->type->is_matrix()) {
714       /* Can't set matrix uniforms (like mat4) with glUniform */
715       _mesa_error(ctx, GL_INVALID_OPERATION,
716                   "glUniform%u(uniform \"%s\"@%d is matrix)",
717                   src_components, uni->name, location);
718       return;
719    }
720 
721    /* Verify that the types are compatible.
722     */
723    const unsigned components = uni->type->is_sampler()
724       ? 1 : uni->type->vector_elements;
725 
726    if (components != src_components) {
727       /* glUniformN() must match float/vecN type */
728       _mesa_error(ctx, GL_INVALID_OPERATION,
729                   "glUniform%u(\"%s\"@%u has %u components, not %u)",
730                   src_components, uni->name, location,
731                   components, src_components);
732       return;
733    }
734 
735    bool match;
736    switch (uni->type->base_type) {
737    case GLSL_TYPE_BOOL:
738       match = (basicType != GLSL_TYPE_DOUBLE);
739       break;
740    case GLSL_TYPE_SAMPLER:
741       match = (basicType == GLSL_TYPE_INT);
742       break;
743    case GLSL_TYPE_IMAGE:
744       match = (basicType == GLSL_TYPE_INT && _mesa_is_desktop_gl(ctx));
745       break;
746    default:
747       match = (basicType == uni->type->base_type);
748       break;
749    }
750 
751    if (!match) {
752       _mesa_error(ctx, GL_INVALID_OPERATION,
753                   "glUniform%u(\"%s\"@%d is %s, not %s)",
754                   src_components, uni->name, location,
755                   glsl_type_name(uni->type->base_type),
756                   glsl_type_name(basicType));
757       return;
758    }
759 
760    if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
761       log_uniform(values, basicType, components, 1, count,
762 		  false, shProg, location, uni);
763    }
764 
765    /* Page 100 (page 116 of the PDF) of the OpenGL 3.0 spec says:
766     *
767     *     "Setting a sampler's value to i selects texture image unit number
768     *     i. The values of i range from zero to the implementation- dependent
769     *     maximum supported number of texture image units."
770     *
771     * In addition, table 2.3, "Summary of GL errors," on page 17 (page 33 of
772     * the PDF) says:
773     *
774     *     "Error         Description                    Offending command
775     *                                                   ignored?
776     *     ...
777     *     INVALID_VALUE  Numeric argument out of range  Yes"
778     *
779     * Based on that, when an invalid sampler is specified, we generate a
780     * GL_INVALID_VALUE error and ignore the command.
781     */
782    if (uni->type->is_sampler()) {
783       for (int i = 0; i < count; i++) {
784 	 const unsigned texUnit = ((unsigned *) values)[i];
785 
786          /* check that the sampler (tex unit index) is legal */
787          if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
788             _mesa_error(ctx, GL_INVALID_VALUE,
789                         "glUniform1i(invalid sampler/tex unit index for "
790 			"uniform %d)",
791                         location);
792             return;
793          }
794       }
795       /* We need to reset the validate flag on changes to samplers in case
796        * two different sampler types are set to the same texture unit.
797        */
798       ctx->_Shader->Validated = GL_FALSE;
799    }
800 
801    if (uni->type->is_image()) {
802       for (int i = 0; i < count; i++) {
803          const int unit = ((GLint *) values)[i];
804 
805          /* check that the image unit is legal */
806          if (unit < 0 || unit >= (int)ctx->Const.MaxImageUnits) {
807             _mesa_error(ctx, GL_INVALID_VALUE,
808                         "glUniform1i(invalid image unit index for uniform %d)",
809                         location);
810             return;
811          }
812       }
813    }
814 
815    /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
816     *
817     *     "When loading N elements starting at an arbitrary position k in a
818     *     uniform declared as an array, elements k through k + N - 1 in the
819     *     array will be replaced with the new values. Values for any array
820     *     element that exceeds the highest array element index used, as
821     *     reported by GetActiveUniform, will be ignored by the GL."
822     *
823     * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
824     * will have already generated an error.
825     */
826    if (uni->array_elements != 0) {
827       count = MIN2(count, (int) (uni->array_elements - offset));
828    }
829 
830    FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
831 
832    /* Store the data in the "actual type" backing storage for the uniform.
833     */
834    if (!uni->type->is_boolean()) {
835       memcpy(&uni->storage[size_mul * components * offset], values,
836 	     sizeof(uni->storage[0]) * components * count * size_mul);
837    } else {
838       const union gl_constant_value *src =
839 	 (const union gl_constant_value *) values;
840       union gl_constant_value *dst = &uni->storage[components * offset];
841       const unsigned elems = components * count;
842 
843       for (unsigned i = 0; i < elems; i++) {
844 	 if (basicType == GLSL_TYPE_FLOAT) {
845             dst[i].i = src[i].f != 0.0f ? ctx->Const.UniformBooleanTrue : 0;
846 	 } else {
847             dst[i].i = src[i].i != 0    ? ctx->Const.UniformBooleanTrue : 0;
848 	 }
849       }
850    }
851 
852    _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
853 
854    /* If the uniform is a sampler, do the extra magic necessary to propagate
855     * the changes through.
856     */
857    if (uni->type->is_sampler()) {
858       bool flushed = false;
859       for (int i = 0; i < MESA_SHADER_STAGES; i++) {
860 	 struct gl_linked_shader *const sh = shProg->_LinkedShaders[i];
861 
862 	 /* If the shader stage doesn't use the sampler uniform, skip this. */
863 	 if (!uni->opaque[i].active)
864 	    continue;
865 
866          bool changed = false;
867          for (int j = 0; j < count; j++) {
868             unsigned unit = uni->opaque[i].index + offset + j;
869             if (sh->Program->SamplerUnits[unit] != ((unsigned *) values)[j]) {
870                sh->Program->SamplerUnits[unit] = ((unsigned *) values)[j];
871                changed = true;
872             }
873          }
874 
875 	 if (changed) {
876 	    if (!flushed) {
877 	       FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
878 	       flushed = true;
879 	    }
880 
881             struct gl_program *const prog = sh->Program;
882 	    _mesa_update_shader_textures_used(shProg, prog);
883             if (ctx->Driver.SamplerUniformChange)
884 	       ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog);
885 	 }
886       }
887    }
888 
889    /* If the uniform is an image, update the mapping from image
890     * uniforms to image units present in the shader data structure.
891     */
892    if (uni->type->is_image()) {
893       for (int i = 0; i < MESA_SHADER_STAGES; i++) {
894 	 if (uni->opaque[i].active) {
895             struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
896 
897             for (int j = 0; j < count; j++)
898                sh->Program->sh.ImageUnits[uni->opaque[i].index + offset + j] =
899                   ((GLint *) values)[j];
900          }
901       }
902 
903       ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;
904    }
905 }
906 
907 /**
908  * Called by glUniformMatrix*() functions.
909  * Note: cols=2, rows=4  ==>  array[2] of vec4
910  */
911 extern "C" void
_mesa_uniform_matrix(struct gl_context * ctx,struct gl_shader_program * shProg,GLuint cols,GLuint rows,GLint location,GLsizei count,GLboolean transpose,const GLvoid * values,enum glsl_base_type basicType)912 _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
913 		     GLuint cols, GLuint rows,
914                      GLint location, GLsizei count,
915                      GLboolean transpose,
916                      const GLvoid *values, enum glsl_base_type basicType)
917 {
918    unsigned offset;
919    unsigned vectors;
920    unsigned components;
921    unsigned elements;
922    int size_mul;
923    struct gl_uniform_storage *const uni =
924       validate_uniform_parameters(ctx, shProg, location, count,
925                                   &offset, "glUniformMatrix");
926    if (uni == NULL)
927       return;
928 
929    if (!uni->type->is_matrix()) {
930       _mesa_error(ctx, GL_INVALID_OPERATION,
931 		  "glUniformMatrix(non-matrix uniform)");
932       return;
933    }
934 
935    assert(basicType == GLSL_TYPE_FLOAT || basicType == GLSL_TYPE_DOUBLE);
936    size_mul = basicType == GLSL_TYPE_DOUBLE ? 2 : 1;
937 
938    assert(!uni->type->is_sampler());
939    vectors = uni->type->matrix_columns;
940    components = uni->type->vector_elements;
941 
942    /* Verify that the types are compatible.  This is greatly simplified for
943     * matrices because they can only have a float base type.
944     */
945    if (vectors != cols || components != rows) {
946       _mesa_error(ctx, GL_INVALID_OPERATION,
947 		  "glUniformMatrix(matrix size mismatch)");
948       return;
949    }
950 
951    /* GL_INVALID_VALUE is generated if `transpose' is not GL_FALSE.
952     * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml
953     */
954    if (transpose) {
955       if (ctx->API == API_OPENGLES2 && ctx->Version < 30) {
956 	 _mesa_error(ctx, GL_INVALID_VALUE,
957 		     "glUniformMatrix(matrix transpose is not GL_FALSE)");
958 	 return;
959       }
960    }
961 
962    /* Section 2.11.7 (Uniform Variables) of the OpenGL 4.2 Core Profile spec
963     * says:
964     *
965     *     "If any of the following conditions occur, an INVALID_OPERATION
966     *     error is generated by the Uniform* commands, and no uniform values
967     *     are changed:
968     *
969     *     ...
970     *
971     *     - if the uniform declared in the shader is not of type boolean and
972     *       the type indicated in the name of the Uniform* command used does
973     *       not match the type of the uniform"
974     *
975     * There are no Boolean matrix types, so we do not need to allow
976     * GLSL_TYPE_BOOL here (as _mesa_uniform does).
977     */
978    if (uni->type->base_type != basicType) {
979       _mesa_error(ctx, GL_INVALID_OPERATION,
980                   "glUniformMatrix%ux%u(\"%s\"@%d is %s, not %s)",
981                   cols, rows, uni->name, location,
982                   glsl_type_name(uni->type->base_type),
983                   glsl_type_name(basicType));
984       return;
985    }
986 
987    if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
988       log_uniform(values, uni->type->base_type, components, vectors, count,
989 		  bool(transpose), shProg, location, uni);
990    }
991 
992    /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
993     *
994     *     "When loading N elements starting at an arbitrary position k in a
995     *     uniform declared as an array, elements k through k + N - 1 in the
996     *     array will be replaced with the new values. Values for any array
997     *     element that exceeds the highest array element index used, as
998     *     reported by GetActiveUniform, will be ignored by the GL."
999     *
1000     * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
1001     * will have already generated an error.
1002     */
1003    if (uni->array_elements != 0) {
1004       count = MIN2(count, (int) (uni->array_elements - offset));
1005    }
1006 
1007    FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
1008 
1009    /* Store the data in the "actual type" backing storage for the uniform.
1010     */
1011    elements = components * vectors;
1012 
1013    if (!transpose) {
1014       memcpy(&uni->storage[size_mul * elements * offset], values,
1015 	     sizeof(uni->storage[0]) * elements * count * size_mul);
1016    } else if (basicType == GLSL_TYPE_FLOAT) {
1017       /* Copy and transpose the matrix.
1018        */
1019       const float *src = (const float *)values;
1020       float *dst = &uni->storage[elements * offset].f;
1021 
1022       for (int i = 0; i < count; i++) {
1023 	 for (unsigned r = 0; r < rows; r++) {
1024 	    for (unsigned c = 0; c < cols; c++) {
1025 	       dst[(c * components) + r] = src[c + (r * vectors)];
1026 	    }
1027 	 }
1028 
1029 	 dst += elements;
1030 	 src += elements;
1031       }
1032    } else {
1033       assert(basicType == GLSL_TYPE_DOUBLE);
1034       const double *src = (const double *)values;
1035       double *dst = (double *)&uni->storage[elements * offset].f;
1036 
1037       for (int i = 0; i < count; i++) {
1038 	 for (unsigned r = 0; r < rows; r++) {
1039 	    for (unsigned c = 0; c < cols; c++) {
1040 	       dst[(c * components) + r] = src[c + (r * vectors)];
1041 	    }
1042 	 }
1043 
1044 	 dst += elements;
1045 	 src += elements;
1046       }
1047    }
1048 
1049    _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
1050 }
1051 
1052 
1053 extern "C" bool
_mesa_sampler_uniforms_are_valid(const struct gl_shader_program * shProg,char * errMsg,size_t errMsgLength)1054 _mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
1055 				 char *errMsg, size_t errMsgLength)
1056 {
1057    /* Shader does not have samplers. */
1058    if (shProg->data->NumUniformStorage == 0)
1059       return true;
1060 
1061    if (!shProg->SamplersValidated) {
1062       _mesa_snprintf(errMsg, errMsgLength,
1063                      "active samplers with a different type "
1064                      "refer to the same texture image unit");
1065       return false;
1066    }
1067    return true;
1068 }
1069 
1070 extern "C" bool
_mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object * pipeline)1071 _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline)
1072 {
1073    /* Section 2.11.11 (Shader Execution), subheading "Validation," of the
1074     * OpenGL 4.1 spec says:
1075     *
1076     *     "[INVALID_OPERATION] is generated by any command that transfers
1077     *     vertices to the GL if:
1078     *
1079     *         ...
1080     *
1081     *         - Any two active samplers in the current program object are of
1082     *           different types, but refer to the same texture image unit.
1083     *
1084     *         - The number of active samplers in the program exceeds the
1085     *           maximum number of texture image units allowed."
1086     */
1087 
1088    GLbitfield mask;
1089    GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
1090    struct gl_linked_shader *shader;
1091    unsigned active_samplers = 0;
1092    const struct gl_shader_program **shProg =
1093       (const struct gl_shader_program **) pipeline->CurrentProgram;
1094 
1095 
1096    memset(TexturesUsed, 0, sizeof(TexturesUsed));
1097 
1098    for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
1099       if (!shProg[idx])
1100          continue;
1101 
1102       shader = shProg[idx]->_LinkedShaders[idx];
1103       if (!shader || !shader->Program)
1104          continue;
1105 
1106       mask = shader->Program->SamplersUsed;
1107       while (mask) {
1108          const int s = u_bit_scan(&mask);
1109          GLuint unit = shader->Program->SamplerUnits[s];
1110          GLuint tgt = shader->Program->sh.SamplerTargets[s];
1111 
1112          /* FIXME: Samplers are initialized to 0 and Mesa doesn't do a
1113           * great job of eliminating unused uniforms currently so for now
1114           * don't throw an error if two sampler types both point to 0.
1115           */
1116          if (unit == 0)
1117             continue;
1118 
1119          if (TexturesUsed[unit] & ~(1 << tgt)) {
1120             pipeline->InfoLog =
1121                ralloc_asprintf(pipeline,
1122                      "Program %d: "
1123                      "Texture unit %d is accessed with 2 different types",
1124                      shProg[idx]->Name, unit);
1125             return false;
1126          }
1127 
1128          TexturesUsed[unit] |= (1 << tgt);
1129       }
1130 
1131       active_samplers += shader->Program->info.num_textures;
1132    }
1133 
1134    if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) {
1135       pipeline->InfoLog =
1136          ralloc_asprintf(pipeline,
1137                          "the number of active samplers %d exceed the "
1138                          "maximum %d",
1139                          active_samplers, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
1140       return false;
1141    }
1142 
1143    return true;
1144 }
1145