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