glsl: move to compiler/
[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 "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 "program/hash_table.h"
39
40
41 extern "C" void GLAPIENTRY
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
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
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 *
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->LinkStatus check out of the main path.
183 */
184 if (unlikely(location >= (GLint) shProg->NumUniformRemapTable)) {
185 if (!shProg->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->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
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->base_type == GLSL_TYPE_DOUBLE ? 2 : 1;
326 const int rmul = returnType == GLSL_TYPE_DOUBLE ? 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 dst[didx].f = *(double *)&src[sidx].f;
386 break;
387 default:
388 assert(!"Should not get here.");
389 break;
390 }
391 break;
392 case GLSL_TYPE_DOUBLE:
393 switch (uni->type->base_type) {
394 case GLSL_TYPE_UINT:
395 *(double *)&dst[didx].f = (double) src[sidx].u;
396 break;
397 case GLSL_TYPE_INT:
398 case GLSL_TYPE_SAMPLER:
399 case GLSL_TYPE_IMAGE:
400 *(double *)&dst[didx].f = (double) src[sidx].i;
401 break;
402 case GLSL_TYPE_BOOL:
403 *(double *)&dst[didx].f = src[sidx].i ? 1.0f : 0.0f;
404 break;
405 case GLSL_TYPE_FLOAT:
406 *(double *)&dst[didx].f = (double) src[sidx].f;
407 break;
408 default:
409 assert(!"Should not get here.");
410 break;
411 }
412 break;
413 case GLSL_TYPE_INT:
414 case GLSL_TYPE_UINT:
415 switch (uni->type->base_type) {
416 case GLSL_TYPE_FLOAT:
417 /* While the GL 3.2 core spec doesn't explicitly
418 * state how conversion of float uniforms to integer
419 * values works, in section 6.2 "State Tables" on
420 * page 267 it says:
421 *
422 * "Unless otherwise specified, when floating
423 * point state is returned as integer values or
424 * integer state is returned as floating-point
425 * values it is converted in the fashion
426 * described in section 6.1.2"
427 *
428 * That section, on page 248, says:
429 *
430 * "If GetIntegerv or GetInteger64v are called,
431 * a floating-point value is rounded to the
432 * nearest integer..."
433 */
434 dst[didx].i = IROUND(src[sidx].f);
435 break;
436 case GLSL_TYPE_BOOL:
437 dst[didx].i = src[sidx].i ? 1 : 0;
438 break;
439 case GLSL_TYPE_DOUBLE:
440 dst[didx].i = IROUNDD(*(double *)&src[sidx].f);
441 break;
442 default:
443 assert(!"Should not get here.");
444 break;
445 }
446 break;
447
448 default:
449 assert(!"Should not get here.");
450 break;
451 }
452 }
453 }
454 }
455 }
456
457 static void
458 log_uniform(const void *values, enum glsl_base_type basicType,
459 unsigned rows, unsigned cols, unsigned count,
460 bool transpose,
461 const struct gl_shader_program *shProg,
462 GLint location,
463 const struct gl_uniform_storage *uni)
464 {
465
466 const union gl_constant_value *v = (const union gl_constant_value *) values;
467 const unsigned elems = rows * cols * count;
468 const char *const extra = (cols == 1) ? "uniform" : "uniform matrix";
469
470 printf("Mesa: set program %u %s \"%s\" (loc %d, type \"%s\", "
471 "transpose = %s) to: ",
472 shProg->Name, extra, uni->name, location, uni->type->name,
473 transpose ? "true" : "false");
474 for (unsigned i = 0; i < elems; i++) {
475 if (i != 0 && ((i % rows) == 0))
476 printf(", ");
477
478 switch (basicType) {
479 case GLSL_TYPE_UINT:
480 printf("%u ", v[i].u);
481 break;
482 case GLSL_TYPE_INT:
483 printf("%d ", v[i].i);
484 break;
485 case GLSL_TYPE_FLOAT:
486 printf("%g ", v[i].f);
487 break;
488 case GLSL_TYPE_DOUBLE:
489 printf("%g ", *(double* )&v[i * 2].f);
490 break;
491 default:
492 assert(!"Should not get here.");
493 break;
494 }
495 }
496 printf("\n");
497 fflush(stdout);
498 }
499
500 #if 0
501 static void
502 log_program_parameters(const struct gl_shader_program *shProg)
503 {
504 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
505 if (shProg->_LinkedShaders[i] == NULL)
506 continue;
507
508 const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program;
509
510 printf("Program %d %s shader parameters:\n",
511 shProg->Name, _mesa_shader_stage_to_string(i));
512 for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) {
513 printf("%s: %p %f %f %f %f\n",
514 prog->Parameters->Parameters[j].Name,
515 prog->Parameters->ParameterValues[j],
516 prog->Parameters->ParameterValues[j][0].f,
517 prog->Parameters->ParameterValues[j][1].f,
518 prog->Parameters->ParameterValues[j][2].f,
519 prog->Parameters->ParameterValues[j][3].f);
520 }
521 }
522 fflush(stdout);
523 }
524 #endif
525
526 /**
527 * Propagate some values from uniform backing storage to driver storage
528 *
529 * Values propagated from uniform backing storage to driver storage
530 * have all format / type conversions previously requested by the
531 * driver applied. This function is most often called by the
532 * implementations of \c glUniform1f, etc. and \c glUniformMatrix2f,
533 * etc.
534 *
535 * \param uni Uniform whose data is to be propagated to driver storage
536 * \param array_index If \c uni is an array, this is the element of
537 * the array to be propagated.
538 * \param count Number of array elements to propagate.
539 */
540 extern "C" void
541 _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni,
542 unsigned array_index,
543 unsigned count)
544 {
545 unsigned i;
546
547 /* vector_elements and matrix_columns can be 0 for samplers.
548 */
549 const unsigned components = MAX2(1, uni->type->vector_elements);
550 const unsigned vectors = MAX2(1, uni->type->matrix_columns);
551 const int dmul = uni->type->base_type == GLSL_TYPE_DOUBLE ? 2 : 1;
552
553 /* Store the data in the driver's requested type in the driver's storage
554 * areas.
555 */
556 unsigned src_vector_byte_stride = components * 4 * dmul;
557
558 for (i = 0; i < uni->num_driver_storage; i++) {
559 struct gl_uniform_driver_storage *const store = &uni->driver_storage[i];
560 uint8_t *dst = (uint8_t *) store->data;
561 const unsigned extra_stride =
562 store->element_stride - (vectors * store->vector_stride);
563 const uint8_t *src =
564 (uint8_t *) (&uni->storage[array_index * (dmul * components * vectors)].i);
565
566 #if 0
567 printf("%s: %p[%d] components=%u vectors=%u count=%u vector_stride=%u "
568 "extra_stride=%u\n",
569 __func__, dst, array_index, components,
570 vectors, count, store->vector_stride, extra_stride);
571 #endif
572
573 dst += array_index * store->element_stride;
574
575 switch (store->format) {
576 case uniform_native: {
577 unsigned j;
578 unsigned v;
579
580 for (j = 0; j < count; j++) {
581 for (v = 0; v < vectors; v++) {
582 memcpy(dst, src, src_vector_byte_stride);
583 src += src_vector_byte_stride;
584 dst += store->vector_stride;
585 }
586
587 dst += extra_stride;
588 }
589 break;
590 }
591
592 case uniform_int_float: {
593 const int *isrc = (const int *) src;
594 unsigned j;
595 unsigned v;
596 unsigned c;
597
598 for (j = 0; j < count; j++) {
599 for (v = 0; v < vectors; v++) {
600 for (c = 0; c < components; c++) {
601 ((float *) dst)[c] = (float) *isrc;
602 isrc++;
603 }
604
605 dst += store->vector_stride;
606 }
607
608 dst += extra_stride;
609 }
610 break;
611 }
612
613 default:
614 assert(!"Should not get here.");
615 break;
616 }
617 }
618 }
619
620
621 /**
622 * Return printable string for a given GLSL_TYPE_x
623 */
624 static const char *
625 glsl_type_name(enum glsl_base_type type)
626 {
627 switch (type) {
628 case GLSL_TYPE_UINT:
629 return "uint";
630 case GLSL_TYPE_INT:
631 return "int";
632 case GLSL_TYPE_FLOAT:
633 return "float";
634 case GLSL_TYPE_DOUBLE:
635 return "double";
636 case GLSL_TYPE_BOOL:
637 return "bool";
638 case GLSL_TYPE_SAMPLER:
639 return "sampler";
640 case GLSL_TYPE_IMAGE:
641 return "image";
642 case GLSL_TYPE_ATOMIC_UINT:
643 return "atomic_uint";
644 case GLSL_TYPE_STRUCT:
645 return "struct";
646 case GLSL_TYPE_INTERFACE:
647 return "interface";
648 case GLSL_TYPE_ARRAY:
649 return "array";
650 case GLSL_TYPE_VOID:
651 return "void";
652 case GLSL_TYPE_ERROR:
653 return "error";
654 default:
655 return "other";
656 }
657 }
658
659
660 /**
661 * Called via glUniform*() functions.
662 */
663 extern "C" void
664 _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
665 GLint location, GLsizei count,
666 const GLvoid *values,
667 enum glsl_base_type basicType,
668 unsigned src_components)
669 {
670 unsigned offset;
671 int size_mul = basicType == GLSL_TYPE_DOUBLE ? 2 : 1;
672
673 struct gl_uniform_storage *const uni =
674 validate_uniform_parameters(ctx, shProg, location, count,
675 &offset, "glUniform");
676 if (uni == NULL)
677 return;
678
679 if (uni->type->is_matrix()) {
680 /* Can't set matrix uniforms (like mat4) with glUniform */
681 _mesa_error(ctx, GL_INVALID_OPERATION,
682 "glUniform%u(uniform \"%s\"@%d is matrix)",
683 src_components, uni->name, location);
684 return;
685 }
686
687 /* Verify that the types are compatible.
688 */
689 const unsigned components = uni->type->is_sampler()
690 ? 1 : uni->type->vector_elements;
691
692 if (components != src_components) {
693 /* glUniformN() must match float/vecN type */
694 _mesa_error(ctx, GL_INVALID_OPERATION,
695 "glUniform%u(\"%s\"@%u has %u components, not %u)",
696 src_components, uni->name, location,
697 components, src_components);
698 return;
699 }
700
701 bool match;
702 switch (uni->type->base_type) {
703 case GLSL_TYPE_BOOL:
704 match = (basicType != GLSL_TYPE_DOUBLE);
705 break;
706 case GLSL_TYPE_SAMPLER:
707 match = (basicType == GLSL_TYPE_INT);
708 break;
709 case GLSL_TYPE_IMAGE:
710 match = (basicType == GLSL_TYPE_INT && _mesa_is_desktop_gl(ctx));
711 break;
712 default:
713 match = (basicType == uni->type->base_type);
714 break;
715 }
716
717 if (!match) {
718 _mesa_error(ctx, GL_INVALID_OPERATION,
719 "glUniform%u(\"%s\"@%d is %s, not %s)",
720 src_components, uni->name, location,
721 glsl_type_name(uni->type->base_type),
722 glsl_type_name(basicType));
723 return;
724 }
725
726 if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
727 log_uniform(values, basicType, components, 1, count,
728 false, shProg, location, uni);
729 }
730
731 /* Page 100 (page 116 of the PDF) of the OpenGL 3.0 spec says:
732 *
733 * "Setting a sampler's value to i selects texture image unit number
734 * i. The values of i range from zero to the implementation- dependent
735 * maximum supported number of texture image units."
736 *
737 * In addition, table 2.3, "Summary of GL errors," on page 17 (page 33 of
738 * the PDF) says:
739 *
740 * "Error Description Offending command
741 * ignored?
742 * ...
743 * INVALID_VALUE Numeric argument out of range Yes"
744 *
745 * Based on that, when an invalid sampler is specified, we generate a
746 * GL_INVALID_VALUE error and ignore the command.
747 */
748 if (uni->type->is_sampler()) {
749 for (int i = 0; i < count; i++) {
750 const unsigned texUnit = ((unsigned *) values)[i];
751
752 /* check that the sampler (tex unit index) is legal */
753 if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
754 _mesa_error(ctx, GL_INVALID_VALUE,
755 "glUniform1i(invalid sampler/tex unit index for "
756 "uniform %d)",
757 location);
758 return;
759 }
760 }
761 /* We need to reset the validate flag on changes to samplers in case
762 * two different sampler types are set to the same texture unit.
763 */
764 ctx->_Shader->Validated = GL_FALSE;
765 }
766
767 if (uni->type->is_image()) {
768 for (int i = 0; i < count; i++) {
769 const int unit = ((GLint *) values)[i];
770
771 /* check that the image unit is legal */
772 if (unit < 0 || unit >= (int)ctx->Const.MaxImageUnits) {
773 _mesa_error(ctx, GL_INVALID_VALUE,
774 "glUniform1i(invalid image unit index for uniform %d)",
775 location);
776 return;
777 }
778 }
779 }
780
781 /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
782 *
783 * "When loading N elements starting at an arbitrary position k in a
784 * uniform declared as an array, elements k through k + N - 1 in the
785 * array will be replaced with the new values. Values for any array
786 * element that exceeds the highest array element index used, as
787 * reported by GetActiveUniform, will be ignored by the GL."
788 *
789 * Clamp 'count' to a valid value. Note that for non-arrays a count > 1
790 * will have already generated an error.
791 */
792 if (uni->array_elements != 0) {
793 count = MIN2(count, (int) (uni->array_elements - offset));
794 }
795
796 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
797
798 /* Store the data in the "actual type" backing storage for the uniform.
799 */
800 if (!uni->type->is_boolean()) {
801 memcpy(&uni->storage[size_mul * components * offset], values,
802 sizeof(uni->storage[0]) * components * count * size_mul);
803 } else {
804 const union gl_constant_value *src =
805 (const union gl_constant_value *) values;
806 union gl_constant_value *dst = &uni->storage[components * offset];
807 const unsigned elems = components * count;
808
809 for (unsigned i = 0; i < elems; i++) {
810 if (basicType == GLSL_TYPE_FLOAT) {
811 dst[i].i = src[i].f != 0.0f ? ctx->Const.UniformBooleanTrue : 0;
812 } else {
813 dst[i].i = src[i].i != 0 ? ctx->Const.UniformBooleanTrue : 0;
814 }
815 }
816 }
817
818 uni->initialized = true;
819
820 _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
821
822 /* If the uniform is a sampler, do the extra magic necessary to propagate
823 * the changes through.
824 */
825 if (uni->type->is_sampler()) {
826 bool flushed = false;
827 for (int i = 0; i < MESA_SHADER_STAGES; i++) {
828 struct gl_shader *const sh = shProg->_LinkedShaders[i];
829
830 /* If the shader stage doesn't use the sampler uniform, skip this.
831 */
832 if (sh == NULL || !uni->opaque[i].active)
833 continue;
834
835 for (int j = 0; j < count; j++) {
836 sh->SamplerUnits[uni->opaque[i].index + offset + j] =
837 ((unsigned *) values)[j];
838 }
839
840 struct gl_program *const prog = sh->Program;
841
842 assert(sizeof(prog->SamplerUnits) == sizeof(sh->SamplerUnits));
843
844 /* Determine if any of the samplers used by this shader stage have
845 * been modified.
846 */
847 bool changed = false;
848 for (unsigned j = 0; j < ARRAY_SIZE(prog->SamplerUnits); j++) {
849 if ((sh->active_samplers & (1U << j)) != 0
850 && (prog->SamplerUnits[j] != sh->SamplerUnits[j])) {
851 changed = true;
852 break;
853 }
854 }
855
856 if (changed) {
857 if (!flushed) {
858 FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
859 flushed = true;
860 }
861
862 memcpy(prog->SamplerUnits,
863 sh->SamplerUnits,
864 sizeof(sh->SamplerUnits));
865
866 _mesa_update_shader_textures_used(shProg, prog);
867 if (ctx->Driver.SamplerUniformChange)
868 ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog);
869 }
870 }
871 }
872
873 /* If the uniform is an image, update the mapping from image
874 * uniforms to image units present in the shader data structure.
875 */
876 if (uni->type->is_image()) {
877 for (int i = 0; i < MESA_SHADER_STAGES; i++) {
878 if (uni->opaque[i].active) {
879 struct gl_shader *sh = shProg->_LinkedShaders[i];
880
881 for (int j = 0; j < count; j++)
882 sh->ImageUnits[uni->opaque[i].index + offset + j] =
883 ((GLint *) values)[j];
884 }
885 }
886
887 ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;
888 }
889 }
890
891 /**
892 * Called by glUniformMatrix*() functions.
893 * Note: cols=2, rows=4 ==> array[2] of vec4
894 */
895 extern "C" void
896 _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
897 GLuint cols, GLuint rows,
898 GLint location, GLsizei count,
899 GLboolean transpose,
900 const GLvoid *values, enum glsl_base_type basicType)
901 {
902 unsigned offset;
903 unsigned vectors;
904 unsigned components;
905 unsigned elements;
906 int size_mul;
907 struct gl_uniform_storage *const uni =
908 validate_uniform_parameters(ctx, shProg, location, count,
909 &offset, "glUniformMatrix");
910 if (uni == NULL)
911 return;
912
913 if (!uni->type->is_matrix()) {
914 _mesa_error(ctx, GL_INVALID_OPERATION,
915 "glUniformMatrix(non-matrix uniform)");
916 return;
917 }
918
919 assert(basicType == GLSL_TYPE_FLOAT || basicType == GLSL_TYPE_DOUBLE);
920 size_mul = basicType == GLSL_TYPE_DOUBLE ? 2 : 1;
921
922 assert(!uni->type->is_sampler());
923 vectors = uni->type->matrix_columns;
924 components = uni->type->vector_elements;
925
926 /* Verify that the types are compatible. This is greatly simplified for
927 * matrices because they can only have a float base type.
928 */
929 if (vectors != cols || components != rows) {
930 _mesa_error(ctx, GL_INVALID_OPERATION,
931 "glUniformMatrix(matrix size mismatch)");
932 return;
933 }
934
935 /* GL_INVALID_VALUE is generated if `transpose' is not GL_FALSE.
936 * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml
937 */
938 if (transpose) {
939 if (ctx->API == API_OPENGLES2 && ctx->Version < 30) {
940 _mesa_error(ctx, GL_INVALID_VALUE,
941 "glUniformMatrix(matrix transpose is not GL_FALSE)");
942 return;
943 }
944 }
945
946 /* Section 2.11.7 (Uniform Variables) of the OpenGL 4.2 Core Profile spec
947 * says:
948 *
949 * "If any of the following conditions occur, an INVALID_OPERATION
950 * error is generated by the Uniform* commands, and no uniform values
951 * are changed:
952 *
953 * ...
954 *
955 * - if the uniform declared in the shader is not of type boolean and
956 * the type indicated in the name of the Uniform* command used does
957 * not match the type of the uniform"
958 *
959 * There are no Boolean matrix types, so we do not need to allow
960 * GLSL_TYPE_BOOL here (as _mesa_uniform does).
961 */
962 if (uni->type->base_type != basicType) {
963 _mesa_error(ctx, GL_INVALID_OPERATION,
964 "glUniformMatrix%ux%u(\"%s\"@%d is %s, not %s)",
965 cols, rows, uni->name, location,
966 glsl_type_name(uni->type->base_type),
967 glsl_type_name(basicType));
968 return;
969 }
970
971 if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
972 log_uniform(values, uni->type->base_type, components, vectors, count,
973 bool(transpose), shProg, location, uni);
974 }
975
976 /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
977 *
978 * "When loading N elements starting at an arbitrary position k in a
979 * uniform declared as an array, elements k through k + N - 1 in the
980 * array will be replaced with the new values. Values for any array
981 * element that exceeds the highest array element index used, as
982 * reported by GetActiveUniform, will be ignored by the GL."
983 *
984 * Clamp 'count' to a valid value. Note that for non-arrays a count > 1
985 * will have already generated an error.
986 */
987 if (uni->array_elements != 0) {
988 count = MIN2(count, (int) (uni->array_elements - offset));
989 }
990
991 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
992
993 /* Store the data in the "actual type" backing storage for the uniform.
994 */
995 elements = components * vectors;
996
997 if (!transpose) {
998 memcpy(&uni->storage[elements * offset], values,
999 sizeof(uni->storage[0]) * elements * count * size_mul);
1000 } else if (basicType == GLSL_TYPE_FLOAT) {
1001 /* Copy and transpose the matrix.
1002 */
1003 const float *src = (const float *)values;
1004 float *dst = &uni->storage[elements * offset].f;
1005
1006 for (int i = 0; i < count; i++) {
1007 for (unsigned r = 0; r < rows; r++) {
1008 for (unsigned c = 0; c < cols; c++) {
1009 dst[(c * components) + r] = src[c + (r * vectors)];
1010 }
1011 }
1012
1013 dst += elements;
1014 src += elements;
1015 }
1016 } else {
1017 assert(basicType == GLSL_TYPE_DOUBLE);
1018 const double *src = (const double *)values;
1019 double *dst = (double *)&uni->storage[elements * offset].f;
1020
1021 for (int i = 0; i < count; i++) {
1022 for (unsigned r = 0; r < rows; r++) {
1023 for (unsigned c = 0; c < cols; c++) {
1024 dst[(c * components) + r] = src[c + (r * vectors)];
1025 }
1026 }
1027
1028 dst += elements;
1029 src += elements;
1030 }
1031 }
1032
1033 uni->initialized = true;
1034
1035 _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
1036 }
1037
1038
1039 extern "C" bool
1040 _mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
1041 char *errMsg, size_t errMsgLength)
1042 {
1043 /* Shader does not have samplers. */
1044 if (shProg->NumUniformStorage == 0)
1045 return true;
1046
1047 if (!shProg->SamplersValidated) {
1048 _mesa_snprintf(errMsg, errMsgLength,
1049 "active samplers with a different type "
1050 "refer to the same texture image unit");
1051 return false;
1052 }
1053 return true;
1054 }
1055
1056 extern "C" bool
1057 _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline)
1058 {
1059 /* Section 2.11.11 (Shader Execution), subheading "Validation," of the
1060 * OpenGL 4.1 spec says:
1061 *
1062 * "[INVALID_OPERATION] is generated by any command that transfers
1063 * vertices to the GL if:
1064 *
1065 * ...
1066 *
1067 * - Any two active samplers in the current program object are of
1068 * different types, but refer to the same texture image unit.
1069 *
1070 * - The number of active samplers in the program exceeds the
1071 * maximum number of texture image units allowed."
1072 */
1073 unsigned active_samplers = 0;
1074 const struct gl_shader_program **shProg =
1075 (const struct gl_shader_program **) pipeline->CurrentProgram;
1076
1077 const glsl_type *unit_types[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
1078 memset(unit_types, 0, sizeof(unit_types));
1079
1080 for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
1081 if (!shProg[idx])
1082 continue;
1083
1084 for (unsigned i = 0; i < shProg[idx]->NumUniformStorage; i++) {
1085 const struct gl_uniform_storage *const storage =
1086 &shProg[idx]->UniformStorage[i];
1087
1088 if (!storage->type->is_sampler())
1089 continue;
1090
1091 active_samplers++;
1092
1093 const unsigned count = MAX2(1, storage->array_elements);
1094 for (unsigned j = 0; j < count; j++) {
1095 const unsigned unit = storage->storage[j].i;
1096
1097 /* FIXME: Samplers are initialized to 0 and Mesa doesn't do a
1098 * great job of eliminating unused uniforms currently so for now
1099 * don't throw an error if two sampler types both point to 0.
1100 */
1101 if (unit == 0)
1102 continue;
1103
1104 /* The types of the samplers associated with a particular texture
1105 * unit must be an exact match. Page 74 (page 89 of the PDF) of
1106 * the OpenGL 3.3 core spec says:
1107 *
1108 * "It is not allowed to have variables of different sampler
1109 * types pointing to the same texture image unit within a
1110 * program object."
1111 */
1112 if (unit_types[unit] == NULL) {
1113 unit_types[unit] = storage->type;
1114 } else if (unit_types[unit] != storage->type) {
1115 pipeline->InfoLog =
1116 ralloc_asprintf(pipeline,
1117 "Texture unit %d is accessed both as %s "
1118 "and %s",
1119 unit, unit_types[unit]->name,
1120 storage->type->name);
1121 return false;
1122 }
1123 }
1124 }
1125 }
1126
1127 if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) {
1128 pipeline->InfoLog =
1129 ralloc_asprintf(pipeline,
1130 "the number of active samplers %d exceed the "
1131 "maximum %d",
1132 active_samplers, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
1133 return false;
1134 }
1135
1136 return true;
1137 }