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