1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved.
6 * Copyright © 2010, 2011 Intel Corporation
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27 #include <stdlib.h>
28 #include <inttypes.h> /* for PRIx64 macro */
29 #include <math.h>
30
31 #include "main/context.h"
32 #include "main/draw_validate.h"
33 #include "main/shaderapi.h"
34 #include "main/shaderobj.h"
35 #include "main/uniforms.h"
36 #include "compiler/glsl/ir.h"
37 #include "compiler/glsl/ir_uniform.h"
38 #include "compiler/glsl/glsl_parser_extras.h"
39 #include "compiler/glsl/program.h"
40 #include "util/bitscan.h"
41
42
43 /* This is one of the few glGet that can be called from the app thread safely.
44 * Only these conditions must be met:
45 * - There are no unfinished glLinkProgram and glDeleteProgram calls
46 * for the program object. This assures that the program object is immutable.
47 * - glthread=true for GL errors to be passed to the driver thread safely
48 *
49 * Program objects can be looked up from any thread because they are part
50 * of the multi-context shared state.
51 */
52 extern "C" void
_mesa_GetActiveUniform_impl(GLuint program,GLuint index,GLsizei maxLength,GLsizei * length,GLint * size,GLenum * type,GLcharARB * nameOut,bool glthread)53 _mesa_GetActiveUniform_impl(GLuint program, GLuint index,
54 GLsizei maxLength, GLsizei *length, GLint *size,
55 GLenum *type, GLcharARB *nameOut, bool glthread)
56 {
57 GET_CURRENT_CONTEXT(ctx);
58 struct gl_shader_program *shProg;
59 struct gl_program_resource *res;
60
61 if (maxLength < 0) {
62 _mesa_error_glthread_safe(ctx, GL_INVALID_VALUE, glthread,
63 "glGetActiveUniform(maxLength < 0)");
64 return;
65 }
66
67 shProg = _mesa_lookup_shader_program_err_glthread(ctx, program, glthread,
68 "glGetActiveUniform");
69 if (!shProg)
70 return;
71
72 res = _mesa_program_resource_find_index((struct gl_shader_program *) shProg,
73 GL_UNIFORM, index);
74
75 if (!res) {
76 _mesa_error_glthread_safe(ctx, GL_INVALID_VALUE, glthread,
77 "glGetActiveUniform(index)");
78 return;
79 }
80
81 if (nameOut)
82 _mesa_get_program_resource_name(shProg, GL_UNIFORM, index, maxLength,
83 length, nameOut, glthread,
84 "glGetActiveUniform");
85 if (type)
86 _mesa_program_resource_prop((struct gl_shader_program *) shProg,
87 res, index, GL_TYPE, (GLint*) type,
88 glthread, "glGetActiveUniform");
89 if (size)
90 _mesa_program_resource_prop((struct gl_shader_program *) shProg,
91 res, index, GL_ARRAY_SIZE, (GLint*) size,
92 glthread, "glGetActiveUniform");
93 }
94
95 extern "C" void GLAPIENTRY
_mesa_GetActiveUniform(GLuint program,GLuint index,GLsizei maxLength,GLsizei * length,GLint * size,GLenum * type,GLcharARB * nameOut)96 _mesa_GetActiveUniform(GLuint program, GLuint index,
97 GLsizei maxLength, GLsizei *length, GLint *size,
98 GLenum *type, GLcharARB *nameOut)
99 {
100 _mesa_GetActiveUniform_impl(program, index, maxLength, length, size,
101 type, nameOut, false);
102 }
103
104 static GLenum
resource_prop_from_uniform_prop(GLenum uni_prop)105 resource_prop_from_uniform_prop(GLenum uni_prop)
106 {
107 switch (uni_prop) {
108 case GL_UNIFORM_TYPE:
109 return GL_TYPE;
110 case GL_UNIFORM_SIZE:
111 return GL_ARRAY_SIZE;
112 case GL_UNIFORM_NAME_LENGTH:
113 return GL_NAME_LENGTH;
114 case GL_UNIFORM_BLOCK_INDEX:
115 return GL_BLOCK_INDEX;
116 case GL_UNIFORM_OFFSET:
117 return GL_OFFSET;
118 case GL_UNIFORM_ARRAY_STRIDE:
119 return GL_ARRAY_STRIDE;
120 case GL_UNIFORM_MATRIX_STRIDE:
121 return GL_MATRIX_STRIDE;
122 case GL_UNIFORM_IS_ROW_MAJOR:
123 return GL_IS_ROW_MAJOR;
124 case GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX:
125 return GL_ATOMIC_COUNTER_BUFFER_INDEX;
126 default:
127 return 0;
128 }
129 }
130
131 extern "C" void GLAPIENTRY
_mesa_GetActiveUniformsiv(GLuint program,GLsizei uniformCount,const GLuint * uniformIndices,GLenum pname,GLint * params)132 _mesa_GetActiveUniformsiv(GLuint program,
133 GLsizei uniformCount,
134 const GLuint *uniformIndices,
135 GLenum pname,
136 GLint *params)
137 {
138 GET_CURRENT_CONTEXT(ctx);
139 struct gl_shader_program *shProg;
140 struct gl_program_resource *res;
141 GLenum res_prop;
142
143 if (uniformCount < 0) {
144 _mesa_error(ctx, GL_INVALID_VALUE,
145 "glGetActiveUniformsiv(uniformCount < 0)");
146 return;
147 }
148
149 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
150 if (!shProg)
151 return;
152
153 res_prop = resource_prop_from_uniform_prop(pname);
154
155 /* We need to first verify that each entry exists as active uniform. If
156 * not, generate error and do not cause any other side effects.
157 *
158 * In the case of and error condition, Page 16 (section 2.3.1 Errors)
159 * of the OpenGL 4.5 spec says:
160 *
161 * "If the generating command modifies values through a pointer argu-
162 * ment, no change is made to these values."
163 */
164 for (int i = 0; i < uniformCount; i++) {
165 if (!_mesa_program_resource_find_index(shProg, GL_UNIFORM,
166 uniformIndices[i])) {
167 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)");
168 return;
169 }
170 }
171
172 for (int i = 0; i < uniformCount; i++) {
173 res = _mesa_program_resource_find_index(shProg, GL_UNIFORM,
174 uniformIndices[i]);
175 if (!_mesa_program_resource_prop(shProg, res, uniformIndices[i],
176 res_prop, ¶ms[i],
177 false, "glGetActiveUniformsiv"))
178 break;
179 }
180 }
181
182 static struct gl_uniform_storage *
validate_uniform_parameters(GLint location,GLsizei count,unsigned * array_index,struct gl_context * ctx,struct gl_shader_program * shProg,const char * caller)183 validate_uniform_parameters(GLint location, GLsizei count,
184 unsigned *array_index,
185 struct gl_context *ctx,
186 struct gl_shader_program *shProg,
187 const char *caller)
188 {
189 if (shProg == NULL) {
190 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", caller);
191 return NULL;
192 }
193
194 /* From page 12 (page 26 of the PDF) of the OpenGL 2.1 spec:
195 *
196 * "If a negative number is provided where an argument of type sizei or
197 * sizeiptr is specified, the error INVALID_VALUE is generated."
198 */
199 if (count < 0) {
200 _mesa_error(ctx, GL_INVALID_VALUE, "%s(count < 0)", caller);
201 return NULL;
202 }
203
204 /* Check that the given location is in bounds of uniform remap table.
205 * Unlinked programs will have NumUniformRemapTable == 0, so we can take
206 * the shProg->data->LinkStatus check out of the main path.
207 */
208 if (unlikely(location >= (GLint) shProg->NumUniformRemapTable)) {
209 if (!shProg->data->LinkStatus)
210 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)",
211 caller);
212 else
213 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
214 caller, location);
215
216 return NULL;
217 }
218
219 if (location == -1) {
220 if (!shProg->data->LinkStatus)
221 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)",
222 caller);
223
224 return NULL;
225 }
226
227 /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
228 *
229 * "If any of the following conditions occur, an INVALID_OPERATION
230 * error is generated by the Uniform* commands, and no uniform values
231 * are changed:
232 *
233 * ...
234 *
235 * - if no variable with a location of location exists in the
236 * program object currently in use and location is not -1,
237 * - if count is greater than one, and the uniform declared in the
238 * shader is not an array variable,
239 */
240 if (location < -1 || !shProg->UniformRemapTable[location]) {
241 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
242 caller, location);
243 return NULL;
244 }
245
246 /* If the driver storage pointer in remap table is -1, we ignore silently.
247 *
248 * GL_ARB_explicit_uniform_location spec says:
249 * "What happens if Uniform* is called with an explicitly defined
250 * uniform location, but that uniform is deemed inactive by the
251 * linker?
252 *
253 * RESOLVED: The call is ignored for inactive uniform variables and
254 * no error is generated."
255 *
256 */
257 if (shProg->UniformRemapTable[location] ==
258 INACTIVE_UNIFORM_EXPLICIT_LOCATION)
259 return NULL;
260
261 struct gl_uniform_storage *const uni = shProg->UniformRemapTable[location];
262
263 /* Even though no location is assigned to a built-in uniform and this
264 * function should already have returned NULL, this test makes it explicit
265 * that we are not allowing to update the value of a built-in.
266 */
267 if (uni->builtin)
268 return NULL;
269
270 if (uni->array_elements == 0) {
271 if (count > 1) {
272 _mesa_error(ctx, GL_INVALID_OPERATION,
273 "%s(count = %u for non-array \"%s\"@%d)",
274 caller, count, uni->name, location);
275 return NULL;
276 }
277
278 assert((location - uni->remap_location) == 0);
279 *array_index = 0;
280 } else {
281 /* The array index specified by the uniform location is just the uniform
282 * location minus the base location of of the uniform.
283 */
284 *array_index = location - uni->remap_location;
285
286 /* If the uniform is an array, check that array_index is in bounds.
287 * array_index is unsigned so no need to check for less than zero.
288 */
289 if (*array_index >= uni->array_elements) {
290 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
291 caller, location);
292 return NULL;
293 }
294 }
295 return uni;
296 }
297
298 /**
299 * Called via glGetUniform[fiui]v() to get the current value of a uniform.
300 */
301 extern "C" void
_mesa_get_uniform(struct gl_context * ctx,GLuint program,GLint location,GLsizei bufSize,enum glsl_base_type returnType,GLvoid * paramsOut)302 _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
303 GLsizei bufSize, enum glsl_base_type returnType,
304 GLvoid *paramsOut)
305 {
306 struct gl_shader_program *shProg =
307 _mesa_lookup_shader_program_err(ctx, program, "glGetUniformfv");
308 unsigned offset;
309
310 struct gl_uniform_storage *const uni =
311 validate_uniform_parameters(location, 1, &offset,
312 ctx, shProg, "glGetUniform");
313 if (uni == NULL) {
314 /* For glGetUniform, page 264 (page 278 of the PDF) of the OpenGL 2.1
315 * spec says:
316 *
317 * "The error INVALID_OPERATION is generated if program has not been
318 * linked successfully, or if location is not a valid location for
319 * program."
320 *
321 * For glUniform, page 82 (page 96 of the PDF) of the OpenGL 2.1 spec
322 * says:
323 *
324 * "If the value of location is -1, the Uniform* commands will
325 * silently ignore the data passed in, and the current uniform
326 * values will not be changed."
327 *
328 * Allowing -1 for the location parameter of glUniform allows
329 * applications to avoid error paths in the case that, for example, some
330 * uniform variable is removed by the compiler / linker after
331 * optimization. In this case, the new value of the uniform is dropped
332 * on the floor. For the case of glGetUniform, there is nothing
333 * sensible to do for a location of -1.
334 *
335 * If the location was -1, validate_unfirom_parameters will return NULL
336 * without raising an error. Raise the error here.
337 */
338 if (location == -1) {
339 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniform(location=%d)",
340 location);
341 }
342
343 return;
344 }
345
346 {
347 unsigned elements = uni->type->components();
348 unsigned components = uni->type->vector_elements;
349
350 const int rmul = glsl_base_type_is_64bit(returnType) ? 2 : 1;
351 int dmul = (uni->type->is_64bit()) ? 2 : 1;
352
353 if ((uni->type->is_sampler() || uni->type->is_image()) &&
354 !uni->is_bindless) {
355 /* Non-bindless samplers/images are represented using unsigned integer
356 * 32-bit, while bindless handles are 64-bit.
357 */
358 dmul = 1;
359 }
360
361 /* Calculate the source base address *BEFORE* modifying elements to
362 * account for the size of the user's buffer.
363 */
364 const union gl_constant_value *src;
365 if (ctx->Const.PackedDriverUniformStorage &&
366 (uni->is_bindless || !uni->type->contains_opaque())) {
367 unsigned dword_elements = elements;
368
369 /* 16-bit uniforms are packed. */
370 if (glsl_base_type_is_16bit(uni->type->base_type)) {
371 dword_elements = DIV_ROUND_UP(components, 2) *
372 uni->type->matrix_columns;
373 }
374
375 src = (gl_constant_value *) uni->driver_storage[0].data +
376 (offset * dword_elements * dmul);
377 } else {
378 src = &uni->storage[offset * elements * dmul];
379 }
380
381 assert(returnType == GLSL_TYPE_FLOAT || returnType == GLSL_TYPE_INT ||
382 returnType == GLSL_TYPE_UINT || returnType == GLSL_TYPE_DOUBLE ||
383 returnType == GLSL_TYPE_UINT64 || returnType == GLSL_TYPE_INT64);
384
385 /* doubles have a different size than the other 3 types */
386 unsigned bytes = sizeof(src[0]) * elements * rmul;
387 if (bufSize < 0 || bytes > (unsigned) bufSize) {
388 _mesa_error(ctx, GL_INVALID_OPERATION,
389 "glGetnUniform*vARB(out of bounds: bufSize is %d,"
390 " but %u bytes are required)", bufSize, bytes);
391 return;
392 }
393
394 /* If the return type and the uniform's native type are "compatible,"
395 * just memcpy the data. If the types are not compatible, perform a
396 * slower convert-and-copy process.
397 */
398 if (returnType == uni->type->base_type ||
399 ((returnType == GLSL_TYPE_INT || returnType == GLSL_TYPE_UINT) &&
400 (uni->type->is_sampler() || uni->type->is_image())) ||
401 (returnType == GLSL_TYPE_UINT64 && uni->is_bindless)) {
402 memcpy(paramsOut, src, bytes);
403 } else {
404 union gl_constant_value *const dst =
405 (union gl_constant_value *) paramsOut;
406 /* This code could be optimized by putting the loop inside the switch
407 * statements. However, this is not expected to be
408 * performance-critical code.
409 */
410 for (unsigned i = 0; i < elements; i++) {
411 int sidx = i * dmul;
412 int didx = i * rmul;
413
414 if (glsl_base_type_is_16bit(uni->type->base_type)) {
415 unsigned column = i / components;
416 unsigned row = i % components;
417 sidx = column * align(components, 2) + row;
418 }
419
420 switch (returnType) {
421 case GLSL_TYPE_FLOAT:
422 switch (uni->type->base_type) {
423 case GLSL_TYPE_FLOAT16:
424 dst[didx].f = _mesa_half_to_float(((uint16_t*)src)[sidx]);
425 break;
426 case GLSL_TYPE_UINT:
427 dst[didx].f = (float) src[sidx].u;
428 break;
429 case GLSL_TYPE_INT:
430 case GLSL_TYPE_SAMPLER:
431 case GLSL_TYPE_IMAGE:
432 dst[didx].f = (float) src[sidx].i;
433 break;
434 case GLSL_TYPE_BOOL:
435 dst[didx].f = src[sidx].i ? 1.0f : 0.0f;
436 break;
437 case GLSL_TYPE_DOUBLE: {
438 double tmp;
439 memcpy(&tmp, &src[sidx].f, sizeof(tmp));
440 dst[didx].f = tmp;
441 break;
442 }
443 case GLSL_TYPE_UINT64: {
444 uint64_t tmp;
445 memcpy(&tmp, &src[sidx].u, sizeof(tmp));
446 dst[didx].f = tmp;
447 break;
448 }
449 case GLSL_TYPE_INT64: {
450 uint64_t tmp;
451 memcpy(&tmp, &src[sidx].i, sizeof(tmp));
452 dst[didx].f = tmp;
453 break;
454 }
455 default:
456 assert(!"Should not get here.");
457 break;
458 }
459 break;
460
461 case GLSL_TYPE_DOUBLE:
462 switch (uni->type->base_type) {
463 case GLSL_TYPE_FLOAT16: {
464 double f = _mesa_half_to_float(((uint16_t*)src)[sidx]);
465 memcpy(&dst[didx].f, &f, sizeof(f));
466 break;
467 }
468 case GLSL_TYPE_UINT: {
469 double tmp = src[sidx].u;
470 memcpy(&dst[didx].f, &tmp, sizeof(tmp));
471 break;
472 }
473 case GLSL_TYPE_INT:
474 case GLSL_TYPE_SAMPLER:
475 case GLSL_TYPE_IMAGE: {
476 double tmp = src[sidx].i;
477 memcpy(&dst[didx].f, &tmp, sizeof(tmp));
478 break;
479 }
480 case GLSL_TYPE_BOOL: {
481 double tmp = src[sidx].i ? 1.0 : 0.0;
482 memcpy(&dst[didx].f, &tmp, sizeof(tmp));
483 break;
484 }
485 case GLSL_TYPE_FLOAT: {
486 double tmp = src[sidx].f;
487 memcpy(&dst[didx].f, &tmp, sizeof(tmp));
488 break;
489 }
490 case GLSL_TYPE_UINT64: {
491 uint64_t tmpu;
492 double tmp;
493 memcpy(&tmpu, &src[sidx].u, sizeof(tmpu));
494 tmp = tmpu;
495 memcpy(&dst[didx].f, &tmp, sizeof(tmp));
496 break;
497 }
498 case GLSL_TYPE_INT64: {
499 int64_t tmpi;
500 double tmp;
501 memcpy(&tmpi, &src[sidx].i, sizeof(tmpi));
502 tmp = tmpi;
503 memcpy(&dst[didx].f, &tmp, sizeof(tmp));
504 break;
505 }
506 default:
507 assert(!"Should not get here.");
508 break;
509 }
510 break;
511
512 case GLSL_TYPE_INT:
513 switch (uni->type->base_type) {
514 case GLSL_TYPE_FLOAT:
515 /* While the GL 3.2 core spec doesn't explicitly
516 * state how conversion of float uniforms to integer
517 * values works, in section 6.2 "State Tables" on
518 * page 267 it says:
519 *
520 * "Unless otherwise specified, when floating
521 * point state is returned as integer values or
522 * integer state is returned as floating-point
523 * values it is converted in the fashion
524 * described in section 6.1.2"
525 *
526 * That section, on page 248, says:
527 *
528 * "If GetIntegerv or GetInteger64v are called,
529 * a floating-point value is rounded to the
530 * nearest integer..."
531 */
532 dst[didx].i = (int64_t) roundf(src[sidx].f);
533 break;
534 case GLSL_TYPE_FLOAT16:
535 dst[didx].i =
536 (int64_t)roundf(_mesa_half_to_float(((uint16_t*)src)[sidx]));
537 break;
538 case GLSL_TYPE_BOOL:
539 dst[didx].i = src[sidx].i ? 1 : 0;
540 break;
541 case GLSL_TYPE_UINT:
542 dst[didx].i = MIN2(src[sidx].i, INT_MAX);
543 break;
544 case GLSL_TYPE_DOUBLE: {
545 double tmp;
546 memcpy(&tmp, &src[sidx].f, sizeof(tmp));
547 dst[didx].i = (int64_t) round(tmp);
548 break;
549 }
550 case GLSL_TYPE_UINT64: {
551 uint64_t tmp;
552 memcpy(&tmp, &src[sidx].u, sizeof(tmp));
553 dst[didx].i = tmp;
554 break;
555 }
556 case GLSL_TYPE_INT64: {
557 int64_t tmp;
558 memcpy(&tmp, &src[sidx].i, sizeof(tmp));
559 dst[didx].i = tmp;
560 break;
561 }
562 default:
563 assert(!"Should not get here.");
564 break;
565 }
566 break;
567
568 case GLSL_TYPE_UINT:
569 switch (uni->type->base_type) {
570 case GLSL_TYPE_FLOAT:
571 /* The spec isn't terribly clear how to handle negative
572 * values with an unsigned return type.
573 *
574 * GL 4.5 section 2.2.2 ("Data Conversions for State
575 * Query Commands") says:
576 *
577 * "If a value is so large in magnitude that it cannot be
578 * represented by the returned data type, then the nearest
579 * value representable using the requested type is
580 * returned."
581 */
582 dst[didx].u = src[sidx].f < 0.0f ?
583 0u : (uint32_t) roundf(src[sidx].f);
584 break;
585 case GLSL_TYPE_FLOAT16: {
586 float f = _mesa_half_to_float(((uint16_t*)src)[sidx]);
587 dst[didx].u = f < 0.0f ? 0u : (uint32_t)roundf(f);
588 break;
589 }
590 case GLSL_TYPE_BOOL:
591 dst[didx].i = src[sidx].i ? 1 : 0;
592 break;
593 case GLSL_TYPE_INT:
594 dst[didx].i = MAX2(src[sidx].i, 0);
595 break;
596 case GLSL_TYPE_DOUBLE: {
597 double tmp;
598 memcpy(&tmp, &src[sidx].f, sizeof(tmp));
599 dst[didx].u = tmp < 0.0 ? 0u : (uint32_t) round(tmp);
600 break;
601 }
602 case GLSL_TYPE_UINT64: {
603 uint64_t tmp;
604 memcpy(&tmp, &src[sidx].u, sizeof(tmp));
605 dst[didx].i = MIN2(tmp, INT_MAX);
606 break;
607 }
608 case GLSL_TYPE_INT64: {
609 int64_t tmp;
610 memcpy(&tmp, &src[sidx].i, sizeof(tmp));
611 dst[didx].i = MAX2(tmp, 0);
612 break;
613 }
614 default:
615 unreachable("invalid uniform type");
616 }
617 break;
618
619 case GLSL_TYPE_INT64:
620 switch (uni->type->base_type) {
621 case GLSL_TYPE_UINT: {
622 uint64_t tmp = src[sidx].u;
623 memcpy(&dst[didx].u, &tmp, sizeof(tmp));
624 break;
625 }
626 case GLSL_TYPE_INT:
627 case GLSL_TYPE_SAMPLER:
628 case GLSL_TYPE_IMAGE: {
629 int64_t tmp = src[sidx].i;
630 memcpy(&dst[didx].u, &tmp, sizeof(tmp));
631 break;
632 }
633 case GLSL_TYPE_BOOL: {
634 int64_t tmp = src[sidx].i ? 1.0f : 0.0f;
635 memcpy(&dst[didx].u, &tmp, sizeof(tmp));
636 break;
637 }
638 case GLSL_TYPE_UINT64: {
639 uint64_t u64;
640 memcpy(&u64, &src[sidx].u, sizeof(u64));
641 int64_t tmp = MIN2(u64, INT_MAX);
642 memcpy(&dst[didx].u, &tmp, sizeof(tmp));
643 break;
644 }
645 case GLSL_TYPE_FLOAT: {
646 int64_t tmp = (int64_t) roundf(src[sidx].f);
647 memcpy(&dst[didx].u, &tmp, sizeof(tmp));
648 break;
649 }
650 case GLSL_TYPE_FLOAT16: {
651 float f = _mesa_half_to_float(((uint16_t*)src)[sidx]);
652 int64_t tmp = (int64_t) roundf(f);
653 memcpy(&dst[didx].u, &tmp, sizeof(tmp));
654 break;
655 }
656 case GLSL_TYPE_DOUBLE: {
657 double d;
658 memcpy(&d, &src[sidx].f, sizeof(d));
659 int64_t tmp = (int64_t) round(d);
660 memcpy(&dst[didx].u, &tmp, sizeof(tmp));
661 break;
662 }
663 default:
664 assert(!"Should not get here.");
665 break;
666 }
667 break;
668
669 case GLSL_TYPE_UINT64:
670 switch (uni->type->base_type) {
671 case GLSL_TYPE_UINT: {
672 uint64_t tmp = src[sidx].u;
673 memcpy(&dst[didx].u, &tmp, sizeof(tmp));
674 break;
675 }
676 case GLSL_TYPE_INT:
677 case GLSL_TYPE_SAMPLER:
678 case GLSL_TYPE_IMAGE: {
679 int64_t tmp = MAX2(src[sidx].i, 0);
680 memcpy(&dst[didx].u, &tmp, sizeof(tmp));
681 break;
682 }
683 case GLSL_TYPE_BOOL: {
684 int64_t tmp = src[sidx].i ? 1.0f : 0.0f;
685 memcpy(&dst[didx].u, &tmp, sizeof(tmp));
686 break;
687 }
688 case GLSL_TYPE_INT64: {
689 uint64_t i64;
690 memcpy(&i64, &src[sidx].i, sizeof(i64));
691 uint64_t tmp = MAX2(i64, 0);
692 memcpy(&dst[didx].u, &tmp, sizeof(tmp));
693 break;
694 }
695 case GLSL_TYPE_FLOAT: {
696 uint64_t tmp = src[sidx].f < 0.0f ?
697 0ull : (uint64_t) roundf(src[sidx].f);
698 memcpy(&dst[didx].u, &tmp, sizeof(tmp));
699 break;
700 }
701 case GLSL_TYPE_FLOAT16: {
702 float f = _mesa_half_to_float(((uint16_t*)src)[sidx]);
703 uint64_t tmp = f < 0.0f ? 0ull : (uint64_t) roundf(f);
704 memcpy(&dst[didx].u, &tmp, sizeof(tmp));
705 break;
706 }
707 case GLSL_TYPE_DOUBLE: {
708 double d;
709 memcpy(&d, &src[sidx].f, sizeof(d));
710 uint64_t tmp = (d < 0.0) ? 0ull : (uint64_t) round(d);
711 memcpy(&dst[didx].u, &tmp, sizeof(tmp));
712 break;
713 }
714 default:
715 assert(!"Should not get here.");
716 break;
717 }
718 break;
719
720 default:
721 assert(!"Should not get here.");
722 break;
723 }
724 }
725 }
726 }
727 }
728
729 static void
log_uniform(const void * values,enum glsl_base_type basicType,unsigned rows,unsigned cols,unsigned count,bool transpose,const struct gl_shader_program * shProg,GLint location,const struct gl_uniform_storage * uni)730 log_uniform(const void *values, enum glsl_base_type basicType,
731 unsigned rows, unsigned cols, unsigned count,
732 bool transpose,
733 const struct gl_shader_program *shProg,
734 GLint location,
735 const struct gl_uniform_storage *uni)
736 {
737
738 const union gl_constant_value *v = (const union gl_constant_value *) values;
739 const unsigned elems = rows * cols * count;
740 const char *const extra = (cols == 1) ? "uniform" : "uniform matrix";
741
742 printf("Mesa: set program %u %s \"%s\" (loc %d, type \"%s\", "
743 "transpose = %s) to: ",
744 shProg->Name, extra, uni->name, location, uni->type->name,
745 transpose ? "true" : "false");
746 for (unsigned i = 0; i < elems; i++) {
747 if (i != 0 && ((i % rows) == 0))
748 printf(", ");
749
750 switch (basicType) {
751 case GLSL_TYPE_UINT:
752 printf("%u ", v[i].u);
753 break;
754 case GLSL_TYPE_INT:
755 printf("%d ", v[i].i);
756 break;
757 case GLSL_TYPE_UINT64: {
758 uint64_t tmp;
759 memcpy(&tmp, &v[i * 2].u, sizeof(tmp));
760 printf("%" PRIu64 " ", tmp);
761 break;
762 }
763 case GLSL_TYPE_INT64: {
764 int64_t tmp;
765 memcpy(&tmp, &v[i * 2].u, sizeof(tmp));
766 printf("%" PRId64 " ", tmp);
767 break;
768 }
769 case GLSL_TYPE_FLOAT:
770 printf("%g ", v[i].f);
771 break;
772 case GLSL_TYPE_DOUBLE: {
773 double tmp;
774 memcpy(&tmp, &v[i * 2].f, sizeof(tmp));
775 printf("%g ", tmp);
776 break;
777 }
778 default:
779 assert(!"Should not get here.");
780 break;
781 }
782 }
783 printf("\n");
784 fflush(stdout);
785 }
786
787 #if 0
788 static void
789 log_program_parameters(const struct gl_shader_program *shProg)
790 {
791 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
792 if (shProg->_LinkedShaders[i] == NULL)
793 continue;
794
795 const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program;
796
797 printf("Program %d %s shader parameters:\n",
798 shProg->Name, _mesa_shader_stage_to_string(i));
799 for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) {
800 unsigned pvo = prog->Parameters->ParameterValueOffset[j];
801 printf("%s: %u %p %f %f %f %f\n",
802 prog->Parameters->Parameters[j].Name,
803 pvo,
804 prog->Parameters->ParameterValues + pvo,
805 prog->Parameters->ParameterValues[pvo].f,
806 prog->Parameters->ParameterValues[pvo + 1].f,
807 prog->Parameters->ParameterValues[pvo + 2].f,
808 prog->Parameters->ParameterValues[pvo + 3].f);
809 }
810 }
811 fflush(stdout);
812 }
813 #endif
814
815 /**
816 * Propagate some values from uniform backing storage to driver storage
817 *
818 * Values propagated from uniform backing storage to driver storage
819 * have all format / type conversions previously requested by the
820 * driver applied. This function is most often called by the
821 * implementations of \c glUniform1f, etc. and \c glUniformMatrix2f,
822 * etc.
823 *
824 * \param uni Uniform whose data is to be propagated to driver storage
825 * \param array_index If \c uni is an array, this is the element of
826 * the array to be propagated.
827 * \param count Number of array elements to propagate.
828 */
829 extern "C" void
_mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage * uni,unsigned array_index,unsigned count)830 _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni,
831 unsigned array_index,
832 unsigned count)
833 {
834 unsigned i;
835
836 const unsigned components = uni->type->vector_elements;
837 const unsigned vectors = uni->type->matrix_columns;
838 const int dmul = uni->type->is_64bit() ? 2 : 1;
839
840 /* Store the data in the driver's requested type in the driver's storage
841 * areas.
842 */
843 unsigned src_vector_byte_stride = components * 4 * dmul;
844
845 for (i = 0; i < uni->num_driver_storage; i++) {
846 struct gl_uniform_driver_storage *const store = &uni->driver_storage[i];
847 uint8_t *dst = (uint8_t *) store->data;
848 const unsigned extra_stride =
849 store->element_stride - (vectors * store->vector_stride);
850 const uint8_t *src =
851 (uint8_t *) (&uni->storage[array_index * (dmul * components * vectors)].i);
852
853 #if 0
854 printf("%s: %p[%d] components=%u vectors=%u count=%u vector_stride=%u "
855 "extra_stride=%u\n",
856 __func__, dst, array_index, components,
857 vectors, count, store->vector_stride, extra_stride);
858 #endif
859
860 dst += array_index * store->element_stride;
861
862 switch (store->format) {
863 case uniform_native: {
864 unsigned j;
865 unsigned v;
866
867 if (src_vector_byte_stride == store->vector_stride) {
868 if (extra_stride) {
869 for (j = 0; j < count; j++) {
870 memcpy(dst, src, src_vector_byte_stride * vectors);
871 src += src_vector_byte_stride * vectors;
872 dst += store->vector_stride * vectors;
873
874 dst += extra_stride;
875 }
876 } else {
877 /* Unigine Heaven benchmark gets here */
878 memcpy(dst, src, src_vector_byte_stride * vectors * count);
879 src += src_vector_byte_stride * vectors * count;
880 dst += store->vector_stride * vectors * count;
881 }
882 } else {
883 for (j = 0; j < count; j++) {
884 for (v = 0; v < vectors; v++) {
885 memcpy(dst, src, src_vector_byte_stride);
886 src += src_vector_byte_stride;
887 dst += store->vector_stride;
888 }
889
890 dst += extra_stride;
891 }
892 }
893 break;
894 }
895
896 case uniform_int_float: {
897 const int *isrc = (const int *) src;
898 unsigned j;
899 unsigned v;
900 unsigned c;
901
902 for (j = 0; j < count; j++) {
903 for (v = 0; v < vectors; v++) {
904 for (c = 0; c < components; c++) {
905 ((float *) dst)[c] = (float) *isrc;
906 isrc++;
907 }
908
909 dst += store->vector_stride;
910 }
911
912 dst += extra_stride;
913 }
914 break;
915 }
916
917 default:
918 assert(!"Should not get here.");
919 break;
920 }
921 }
922 }
923
924
925 /**
926 * Return printable string for a given GLSL_TYPE_x
927 */
928 static const char *
glsl_type_name(enum glsl_base_type type)929 glsl_type_name(enum glsl_base_type type)
930 {
931 switch (type) {
932 case GLSL_TYPE_UINT:
933 return "uint";
934 case GLSL_TYPE_INT:
935 return "int";
936 case GLSL_TYPE_FLOAT:
937 return "float";
938 case GLSL_TYPE_DOUBLE:
939 return "double";
940 case GLSL_TYPE_UINT64:
941 return "uint64";
942 case GLSL_TYPE_INT64:
943 return "int64";
944 case GLSL_TYPE_BOOL:
945 return "bool";
946 case GLSL_TYPE_SAMPLER:
947 return "sampler";
948 case GLSL_TYPE_IMAGE:
949 return "image";
950 case GLSL_TYPE_ATOMIC_UINT:
951 return "atomic_uint";
952 case GLSL_TYPE_STRUCT:
953 return "struct";
954 case GLSL_TYPE_INTERFACE:
955 return "interface";
956 case GLSL_TYPE_ARRAY:
957 return "array";
958 case GLSL_TYPE_VOID:
959 return "void";
960 case GLSL_TYPE_ERROR:
961 return "error";
962 default:
963 return "other";
964 }
965 }
966
967
968 static struct gl_uniform_storage *
validate_uniform(GLint location,GLsizei count,const GLvoid * values,unsigned * offset,struct gl_context * ctx,struct gl_shader_program * shProg,enum glsl_base_type basicType,unsigned src_components)969 validate_uniform(GLint location, GLsizei count, const GLvoid *values,
970 unsigned *offset, struct gl_context *ctx,
971 struct gl_shader_program *shProg,
972 enum glsl_base_type basicType, unsigned src_components)
973 {
974 struct gl_uniform_storage *const uni =
975 validate_uniform_parameters(location, count, offset,
976 ctx, shProg, "glUniform");
977 if (uni == NULL)
978 return NULL;
979
980 if (uni->type->is_matrix()) {
981 /* Can't set matrix uniforms (like mat4) with glUniform */
982 _mesa_error(ctx, GL_INVALID_OPERATION,
983 "glUniform%u(uniform \"%s\"@%d is matrix)",
984 src_components, uni->name, location);
985 return NULL;
986 }
987
988 /* Verify that the types are compatible. */
989 const unsigned components = uni->type->vector_elements;
990
991 if (components != src_components) {
992 /* glUniformN() must match float/vecN type */
993 _mesa_error(ctx, GL_INVALID_OPERATION,
994 "glUniform%u(\"%s\"@%u has %u components, not %u)",
995 src_components, uni->name, location,
996 components, src_components);
997 return NULL;
998 }
999
1000 bool match;
1001 switch (uni->type->base_type) {
1002 case GLSL_TYPE_BOOL:
1003 match = (basicType != GLSL_TYPE_DOUBLE);
1004 break;
1005 case GLSL_TYPE_SAMPLER:
1006 match = (basicType == GLSL_TYPE_INT);
1007 break;
1008 case GLSL_TYPE_IMAGE:
1009 match = (basicType == GLSL_TYPE_INT && _mesa_is_desktop_gl(ctx));
1010 break;
1011 case GLSL_TYPE_FLOAT16:
1012 match = basicType == GLSL_TYPE_FLOAT;
1013 break;
1014 default:
1015 match = (basicType == uni->type->base_type);
1016 break;
1017 }
1018
1019 if (!match) {
1020 _mesa_error(ctx, GL_INVALID_OPERATION,
1021 "glUniform%u(\"%s\"@%d is %s, not %s)",
1022 src_components, uni->name, location,
1023 glsl_type_name(uni->type->base_type),
1024 glsl_type_name(basicType));
1025 return NULL;
1026 }
1027
1028 if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
1029 log_uniform(values, basicType, components, 1, count,
1030 false, shProg, location, uni);
1031 }
1032
1033 /* Page 100 (page 116 of the PDF) of the OpenGL 3.0 spec says:
1034 *
1035 * "Setting a sampler's value to i selects texture image unit number
1036 * i. The values of i range from zero to the implementation- dependent
1037 * maximum supported number of texture image units."
1038 *
1039 * In addition, table 2.3, "Summary of GL errors," on page 17 (page 33 of
1040 * the PDF) says:
1041 *
1042 * "Error Description Offending command
1043 * ignored?
1044 * ...
1045 * INVALID_VALUE Numeric argument out of range Yes"
1046 *
1047 * Based on that, when an invalid sampler is specified, we generate a
1048 * GL_INVALID_VALUE error and ignore the command.
1049 */
1050 if (uni->type->is_sampler()) {
1051 for (int i = 0; i < count; i++) {
1052 const unsigned texUnit = ((unsigned *) values)[i];
1053
1054 /* check that the sampler (tex unit index) is legal */
1055 if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
1056 _mesa_error(ctx, GL_INVALID_VALUE,
1057 "glUniform1i(invalid sampler/tex unit index for "
1058 "uniform %d)", location);
1059 return NULL;
1060 }
1061 }
1062 /* We need to reset the validate flag on changes to samplers in case
1063 * two different sampler types are set to the same texture unit.
1064 */
1065 ctx->_Shader->Validated = ctx->_Shader->UserValidated = GL_FALSE;
1066 }
1067
1068 if (uni->type->is_image()) {
1069 for (int i = 0; i < count; i++) {
1070 const int unit = ((GLint *) values)[i];
1071
1072 /* check that the image unit is legal */
1073 if (unit < 0 || unit >= (int)ctx->Const.MaxImageUnits) {
1074 _mesa_error(ctx, GL_INVALID_VALUE,
1075 "glUniform1i(invalid image unit index for uniform %d)",
1076 location);
1077 return NULL;
1078 }
1079 }
1080 }
1081
1082 return uni;
1083 }
1084
1085 void
_mesa_flush_vertices_for_uniforms(struct gl_context * ctx,const struct gl_uniform_storage * uni)1086 _mesa_flush_vertices_for_uniforms(struct gl_context *ctx,
1087 const struct gl_uniform_storage *uni)
1088 {
1089 /* Opaque uniforms have no storage unless they are bindless */
1090 if (!uni->is_bindless && uni->type->contains_opaque()) {
1091 /* Samplers flush on demand and ignore redundant updates. */
1092 if (!uni->type->is_sampler())
1093 FLUSH_VERTICES(ctx, 0, 0);
1094 return;
1095 }
1096
1097 uint64_t new_driver_state = 0;
1098 unsigned mask = uni->active_shader_mask;
1099
1100 while (mask) {
1101 unsigned index = u_bit_scan(&mask);
1102
1103 assert(index < MESA_SHADER_STAGES);
1104 new_driver_state |= ctx->DriverFlags.NewShaderConstants[index];
1105 }
1106
1107 FLUSH_VERTICES(ctx, new_driver_state ? 0 : _NEW_PROGRAM_CONSTANTS, 0);
1108 ctx->NewDriverState |= new_driver_state;
1109 }
1110
1111 static bool
copy_uniforms_to_storage(gl_constant_value * storage,struct gl_uniform_storage * uni,struct gl_context * ctx,GLsizei count,const GLvoid * values,const int size_mul,const unsigned offset,const unsigned components,enum glsl_base_type basicType,bool flush)1112 copy_uniforms_to_storage(gl_constant_value *storage,
1113 struct gl_uniform_storage *uni,
1114 struct gl_context *ctx, GLsizei count,
1115 const GLvoid *values, const int size_mul,
1116 const unsigned offset, const unsigned components,
1117 enum glsl_base_type basicType, bool flush)
1118 {
1119 const gl_constant_value *src = (const gl_constant_value*)values;
1120 bool copy_as_uint64 = uni->is_bindless &&
1121 (uni->type->is_sampler() || uni->type->is_image());
1122 bool copy_to_float16 = uni->type->base_type == GLSL_TYPE_FLOAT16;
1123
1124 if (!uni->type->is_boolean() && !copy_as_uint64 && !copy_to_float16) {
1125 unsigned size = sizeof(storage[0]) * components * count * size_mul;
1126
1127 if (!memcmp(storage, values, size))
1128 return false;
1129
1130 if (flush)
1131 _mesa_flush_vertices_for_uniforms(ctx, uni);
1132
1133 memcpy(storage, values, size);
1134 return true;
1135 } else if (copy_to_float16) {
1136 assert(ctx->Const.PackedDriverUniformStorage);
1137 const unsigned dst_components = align(components, 2);
1138 uint16_t *dst = (uint16_t*)storage;
1139
1140 int i = 0;
1141 unsigned c = 0;
1142
1143 if (flush) {
1144 /* Find the first element that's different. */
1145 for (; i < count; i++) {
1146 for (; c < components; c++) {
1147 if (dst[c] != _mesa_float_to_half(src[c].f)) {
1148 _mesa_flush_vertices_for_uniforms(ctx, uni);
1149 flush = false;
1150 goto break_loops;
1151 }
1152 }
1153 c = 0;
1154 dst += dst_components;
1155 src += components;
1156 }
1157 break_loops:
1158 if (flush)
1159 return false; /* No change. */
1160 }
1161
1162 /* Set the remaining elements. We know that at least 1 element is
1163 * different and that we have flushed.
1164 */
1165 for (; i < count; i++) {
1166 for (; c < components; c++)
1167 dst[c] = _mesa_float_to_half(src[c].f);
1168
1169 c = 0;
1170 dst += dst_components;
1171 src += components;
1172 }
1173
1174 return true;
1175 } else if (copy_as_uint64) {
1176 const unsigned elems = components * count;
1177 uint64_t *dst = (uint64_t*)storage;
1178 unsigned i = 0;
1179
1180 if (flush) {
1181 /* Find the first element that's different. */
1182 for (; i < elems; i++) {
1183 if (dst[i] != src[i].u) {
1184 _mesa_flush_vertices_for_uniforms(ctx, uni);
1185 flush = false;
1186 break;
1187 }
1188 }
1189 if (flush)
1190 return false; /* No change. */
1191 }
1192
1193 /* Set the remaining elements. We know that at least 1 element is
1194 * different and that we have flushed.
1195 */
1196 for (; i < elems; i++)
1197 dst[i] = src[i].u;
1198
1199 return true;
1200 } else {
1201 const unsigned elems = components * count;
1202 gl_constant_value *dst = storage;
1203
1204 if (basicType == GLSL_TYPE_FLOAT) {
1205 unsigned i = 0;
1206
1207 if (flush) {
1208 /* Find the first element that's different. */
1209 for (; i < elems; i++) {
1210 if (dst[i].u !=
1211 (src[i].f != 0.0f ? ctx->Const.UniformBooleanTrue : 0)) {
1212 _mesa_flush_vertices_for_uniforms(ctx, uni);
1213 flush = false;
1214 break;
1215 }
1216 }
1217 if (flush)
1218 return false; /* No change. */
1219 }
1220
1221 /* Set the remaining elements. We know that at least 1 element is
1222 * different and that we have flushed.
1223 */
1224 for (; i < elems; i++)
1225 dst[i].u = src[i].f != 0.0f ? ctx->Const.UniformBooleanTrue : 0;
1226
1227 return true;
1228 } else {
1229 unsigned i = 0;
1230
1231 if (flush) {
1232 /* Find the first element that's different. */
1233 for (; i < elems; i++) {
1234 if (dst[i].u !=
1235 (src[i].u ? ctx->Const.UniformBooleanTrue : 0)) {
1236 _mesa_flush_vertices_for_uniforms(ctx, uni);
1237 flush = false;
1238 break;
1239 }
1240 }
1241 if (flush)
1242 return false; /* No change. */
1243 }
1244
1245 /* Set the remaining elements. We know that at least 1 element is
1246 * different and that we have flushed.
1247 */
1248 for (; i < elems; i++)
1249 dst[i].u = src[i].u ? ctx->Const.UniformBooleanTrue : 0;
1250
1251 return true;
1252 }
1253 }
1254 }
1255
1256
1257 /**
1258 * Called via glUniform*() functions.
1259 */
1260 extern "C" void
_mesa_uniform(GLint location,GLsizei count,const GLvoid * values,struct gl_context * ctx,struct gl_shader_program * shProg,enum glsl_base_type basicType,unsigned src_components)1261 _mesa_uniform(GLint location, GLsizei count, const GLvoid *values,
1262 struct gl_context *ctx, struct gl_shader_program *shProg,
1263 enum glsl_base_type basicType, unsigned src_components)
1264 {
1265 unsigned offset;
1266 int size_mul = glsl_base_type_is_64bit(basicType) ? 2 : 1;
1267
1268 struct gl_uniform_storage *uni;
1269 if (_mesa_is_no_error_enabled(ctx)) {
1270 /* From Seciton 7.6 (UNIFORM VARIABLES) of the OpenGL 4.5 spec:
1271 *
1272 * "If the value of location is -1, the Uniform* commands will
1273 * silently ignore the data passed in, and the current uniform values
1274 * will not be changed.
1275 */
1276 if (location == -1)
1277 return;
1278
1279 if (location >= (int)shProg->NumUniformRemapTable)
1280 return;
1281
1282 uni = shProg->UniformRemapTable[location];
1283 if (!uni || uni == INACTIVE_UNIFORM_EXPLICIT_LOCATION)
1284 return;
1285
1286 /* The array index specified by the uniform location is just the
1287 * uniform location minus the base location of of the uniform.
1288 */
1289 assert(uni->array_elements > 0 || location == (int)uni->remap_location);
1290 offset = location - uni->remap_location;
1291 } else {
1292 uni = validate_uniform(location, count, values, &offset, ctx, shProg,
1293 basicType, src_components);
1294 if (!uni)
1295 return;
1296 }
1297
1298 const unsigned components = uni->type->vector_elements;
1299
1300 /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
1301 *
1302 * "When loading N elements starting at an arbitrary position k in a
1303 * uniform declared as an array, elements k through k + N - 1 in the
1304 * array will be replaced with the new values. Values for any array
1305 * element that exceeds the highest array element index used, as
1306 * reported by GetActiveUniform, will be ignored by the GL."
1307 *
1308 * Clamp 'count' to a valid value. Note that for non-arrays a count > 1
1309 * will have already generated an error.
1310 */
1311 if (uni->array_elements != 0) {
1312 count = MIN2(count, (int) (uni->array_elements - offset));
1313 }
1314
1315 /* Store the data in the "actual type" backing storage for the uniform.
1316 */
1317 bool ctx_flushed = false;
1318 gl_constant_value *storage;
1319 if (ctx->Const.PackedDriverUniformStorage &&
1320 (uni->is_bindless || !uni->type->contains_opaque())) {
1321 for (unsigned s = 0; s < uni->num_driver_storage; s++) {
1322 unsigned dword_components = components;
1323
1324 /* 16-bit uniforms are packed. */
1325 if (glsl_base_type_is_16bit(uni->type->base_type))
1326 dword_components = DIV_ROUND_UP(dword_components, 2);
1327
1328 storage = (gl_constant_value *)
1329 uni->driver_storage[s].data + (size_mul * offset * dword_components);
1330
1331 if (copy_uniforms_to_storage(storage, uni, ctx, count, values, size_mul,
1332 offset, components, basicType, !ctx_flushed))
1333 ctx_flushed = true;
1334 }
1335 } else {
1336 storage = &uni->storage[size_mul * components * offset];
1337 if (copy_uniforms_to_storage(storage, uni, ctx, count, values, size_mul,
1338 offset, components, basicType, !ctx_flushed)) {
1339 _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
1340 ctx_flushed = true;
1341 }
1342 }
1343 /* Return early if possible. Bindless samplers need to be processed
1344 * because of the !sampler->bound codepath below.
1345 */
1346 if (!ctx_flushed && !(uni->type->is_sampler() && uni->is_bindless))
1347 return; /* no change in uniform values */
1348
1349 /* If the uniform is a sampler, do the extra magic necessary to propagate
1350 * the changes through.
1351 */
1352 if (uni->type->is_sampler()) {
1353 /* Note that samplers are the only uniforms that don't call
1354 * FLUSH_VERTICES above.
1355 */
1356 bool flushed = false;
1357 bool any_changed = false;
1358
1359 shProg->SamplersValidated = GL_TRUE;
1360
1361 for (int i = 0; i < MESA_SHADER_STAGES; i++) {
1362 struct gl_linked_shader *const sh = shProg->_LinkedShaders[i];
1363
1364 /* If the shader stage doesn't use the sampler uniform, skip this. */
1365 if (!uni->opaque[i].active)
1366 continue;
1367
1368 bool changed = false;
1369 for (int j = 0; j < count; j++) {
1370 unsigned unit = uni->opaque[i].index + offset + j;
1371 unsigned value = ((unsigned *)values)[j];
1372
1373 if (uni->is_bindless) {
1374 struct gl_bindless_sampler *sampler =
1375 &sh->Program->sh.BindlessSamplers[unit];
1376
1377 /* Mark this bindless sampler as bound to a texture unit.
1378 */
1379 if (sampler->unit != value || !sampler->bound) {
1380 if (!flushed) {
1381 FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT | _NEW_PROGRAM, 0);
1382 flushed = true;
1383 }
1384 sampler->unit = value;
1385 changed = true;
1386 }
1387 sampler->bound = true;
1388 sh->Program->sh.HasBoundBindlessSampler = true;
1389 } else {
1390 if (sh->Program->SamplerUnits[unit] != value) {
1391 if (!flushed) {
1392 FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT | _NEW_PROGRAM, 0);
1393 flushed = true;
1394 }
1395 sh->Program->SamplerUnits[unit] = value;
1396 changed = true;
1397 }
1398 }
1399 }
1400
1401 if (changed) {
1402 struct gl_program *const prog = sh->Program;
1403 _mesa_update_shader_textures_used(shProg, prog);
1404 if (ctx->Driver.SamplerUniformChange)
1405 ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog);
1406 any_changed = true;
1407 }
1408 }
1409
1410 if (any_changed)
1411 _mesa_update_valid_to_render_state(ctx);
1412 }
1413
1414 /* If the uniform is an image, update the mapping from image
1415 * uniforms to image units present in the shader data structure.
1416 */
1417 if (uni->type->is_image()) {
1418 for (int i = 0; i < MESA_SHADER_STAGES; i++) {
1419 struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
1420
1421 /* If the shader stage doesn't use the image uniform, skip this. */
1422 if (!uni->opaque[i].active)
1423 continue;
1424
1425 for (int j = 0; j < count; j++) {
1426 unsigned unit = uni->opaque[i].index + offset + j;
1427 unsigned value = ((unsigned *)values)[j];
1428
1429 if (uni->is_bindless) {
1430 struct gl_bindless_image *image =
1431 &sh->Program->sh.BindlessImages[unit];
1432
1433 /* Mark this bindless image as bound to an image unit.
1434 */
1435 image->unit = value;
1436 image->bound = true;
1437 sh->Program->sh.HasBoundBindlessImage = true;
1438 } else {
1439 sh->Program->sh.ImageUnits[unit] = value;
1440 }
1441 }
1442 }
1443
1444 ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;
1445 }
1446 }
1447
1448
1449 static bool
copy_uniform_matrix_to_storage(struct gl_context * ctx,gl_constant_value * storage,struct gl_uniform_storage * const uni,unsigned count,const void * values,const unsigned size_mul,const unsigned offset,const unsigned components,const unsigned vectors,bool transpose,unsigned cols,unsigned rows,enum glsl_base_type basicType,bool flush)1450 copy_uniform_matrix_to_storage(struct gl_context *ctx,
1451 gl_constant_value *storage,
1452 struct gl_uniform_storage *const uni,
1453 unsigned count, const void *values,
1454 const unsigned size_mul, const unsigned offset,
1455 const unsigned components,
1456 const unsigned vectors, bool transpose,
1457 unsigned cols, unsigned rows,
1458 enum glsl_base_type basicType, bool flush)
1459 {
1460 const unsigned elements = components * vectors;
1461 const unsigned size = sizeof(storage[0]) * elements * count * size_mul;
1462
1463 if (uni->type->base_type == GLSL_TYPE_FLOAT16) {
1464 assert(ctx->Const.PackedDriverUniformStorage);
1465 const unsigned dst_components = align(components, 2);
1466 const unsigned dst_elements = dst_components * vectors;
1467
1468 if (!transpose) {
1469 const float *src = (const float *)values;
1470 uint16_t *dst = (uint16_t*)storage;
1471
1472 unsigned i = 0, r = 0, c = 0;
1473
1474 if (flush) {
1475 /* Find the first element that's different. */
1476 for (; i < count; i++) {
1477 for (; c < cols; c++) {
1478 for (; r < rows; r++) {
1479 if (dst[(c * dst_components) + r] !=
1480 _mesa_float_to_half(src[(c * components) + r])) {
1481 _mesa_flush_vertices_for_uniforms(ctx, uni);
1482 flush = false;
1483 goto break_loops_16bit;
1484 }
1485 }
1486 r = 0;
1487 }
1488 c = 0;
1489 dst += dst_elements;
1490 src += elements;
1491 }
1492
1493 break_loops_16bit:
1494 if (flush)
1495 return false; /* No change. */
1496 }
1497
1498 /* Set the remaining elements. We know that at least 1 element is
1499 * different and that we have flushed.
1500 */
1501 for (; i < count; i++) {
1502 for (; c < cols; c++) {
1503 for (; r < rows; r++) {
1504 dst[(c * dst_components) + r] =
1505 _mesa_float_to_half(src[(c * components) + r]);
1506 }
1507 r = 0;
1508 }
1509 c = 0;
1510 dst += dst_elements;
1511 src += elements;
1512 }
1513 return true;
1514 } else {
1515 /* Transpose the matrix. */
1516 const float *src = (const float *)values;
1517 uint16_t *dst = (uint16_t*)storage;
1518
1519 unsigned i = 0, r = 0, c = 0;
1520
1521 if (flush) {
1522 /* Find the first element that's different. */
1523 for (; i < count; i++) {
1524 for (; r < rows; r++) {
1525 for (; c < cols; c++) {
1526 if (dst[(c * dst_components) + r] !=
1527 _mesa_float_to_half(src[c + (r * vectors)])) {
1528 _mesa_flush_vertices_for_uniforms(ctx, uni);
1529 flush = false;
1530 goto break_loops_16bit_transpose;
1531 }
1532 }
1533 c = 0;
1534 }
1535 r = 0;
1536 dst += elements;
1537 src += elements;
1538 }
1539
1540 break_loops_16bit_transpose:
1541 if (flush)
1542 return false; /* No change. */
1543 }
1544
1545 /* Set the remaining elements. We know that at least 1 element is
1546 * different and that we have flushed.
1547 */
1548 for (; i < count; i++) {
1549 for (; r < rows; r++) {
1550 for (; c < cols; c++) {
1551 dst[(c * dst_components) + r] =
1552 _mesa_float_to_half(src[c + (r * vectors)]);
1553 }
1554 c = 0;
1555 }
1556 r = 0;
1557 dst += elements;
1558 src += elements;
1559 }
1560 return true;
1561 }
1562 } else if (!transpose) {
1563 if (!memcmp(storage, values, size))
1564 return false;
1565
1566 if (flush)
1567 _mesa_flush_vertices_for_uniforms(ctx, uni);
1568
1569 memcpy(storage, values, size);
1570 return true;
1571 } else if (basicType == GLSL_TYPE_FLOAT) {
1572 /* Transpose the matrix. */
1573 const float *src = (const float *)values;
1574 float *dst = (float*)storage;
1575
1576 unsigned i = 0, r = 0, c = 0;
1577
1578 if (flush) {
1579 /* Find the first element that's different. */
1580 for (; i < count; i++) {
1581 for (; r < rows; r++) {
1582 for (; c < cols; c++) {
1583 if (dst[(c * components) + r] != src[c + (r * vectors)]) {
1584 _mesa_flush_vertices_for_uniforms(ctx, uni);
1585 flush = false;
1586 goto break_loops;
1587 }
1588 }
1589 c = 0;
1590 }
1591 r = 0;
1592 dst += elements;
1593 src += elements;
1594 }
1595
1596 break_loops:
1597 if (flush)
1598 return false; /* No change. */
1599 }
1600
1601 /* Set the remaining elements. We know that at least 1 element is
1602 * different and that we have flushed.
1603 */
1604 for (; i < count; i++) {
1605 for (; r < rows; r++) {
1606 for (; c < cols; c++)
1607 dst[(c * components) + r] = src[c + (r * vectors)];
1608 c = 0;
1609 }
1610 r = 0;
1611 dst += elements;
1612 src += elements;
1613 }
1614 return true;
1615 } else {
1616 assert(basicType == GLSL_TYPE_DOUBLE);
1617 const double *src = (const double *)values;
1618 double *dst = (double*)storage;
1619
1620 unsigned i = 0, r = 0, c = 0;
1621
1622 if (flush) {
1623 /* Find the first element that's different. */
1624 for (; i < count; i++) {
1625 for (; r < rows; r++) {
1626 for (; c < cols; c++) {
1627 if (dst[(c * components) + r] != src[c + (r * vectors)]) {
1628 _mesa_flush_vertices_for_uniforms(ctx, uni);
1629 flush = false;
1630 goto break_loops2;
1631 }
1632 }
1633 c = 0;
1634 }
1635 r = 0;
1636 dst += elements;
1637 src += elements;
1638 }
1639
1640 break_loops2:
1641 if (flush)
1642 return false; /* No change. */
1643 }
1644
1645 /* Set the remaining elements. We know that at least 1 element is
1646 * different and that we have flushed.
1647 */
1648 for (; i < count; i++) {
1649 for (; r < rows; r++) {
1650 for (; c < cols; c++)
1651 dst[(c * components) + r] = src[c + (r * vectors)];
1652 c = 0;
1653 }
1654 r = 0;
1655 dst += elements;
1656 src += elements;
1657 }
1658 return true;
1659 }
1660 }
1661
1662
1663 /**
1664 * Called by glUniformMatrix*() functions.
1665 * Note: cols=2, rows=4 ==> array[2] of vec4
1666 */
1667 extern "C" void
_mesa_uniform_matrix(GLint location,GLsizei count,GLboolean transpose,const void * values,struct gl_context * ctx,struct gl_shader_program * shProg,GLuint cols,GLuint rows,enum glsl_base_type basicType)1668 _mesa_uniform_matrix(GLint location, GLsizei count,
1669 GLboolean transpose, const void *values,
1670 struct gl_context *ctx, struct gl_shader_program *shProg,
1671 GLuint cols, GLuint rows, enum glsl_base_type basicType)
1672 {
1673 unsigned offset;
1674 struct gl_uniform_storage *const uni =
1675 validate_uniform_parameters(location, count, &offset,
1676 ctx, shProg, "glUniformMatrix");
1677 if (uni == NULL)
1678 return;
1679
1680 /* GL_INVALID_VALUE is generated if `transpose' is not GL_FALSE.
1681 * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml
1682 */
1683 if (transpose) {
1684 if (ctx->API == API_OPENGLES2 && ctx->Version < 30) {
1685 _mesa_error(ctx, GL_INVALID_VALUE,
1686 "glUniformMatrix(matrix transpose is not GL_FALSE)");
1687 return;
1688 }
1689 }
1690
1691 if (!uni->type->is_matrix()) {
1692 _mesa_error(ctx, GL_INVALID_OPERATION,
1693 "glUniformMatrix(non-matrix uniform)");
1694 return;
1695 }
1696
1697 assert(basicType == GLSL_TYPE_FLOAT || basicType == GLSL_TYPE_DOUBLE);
1698 const unsigned size_mul = basicType == GLSL_TYPE_DOUBLE ? 2 : 1;
1699
1700 assert(!uni->type->is_sampler());
1701 const unsigned vectors = uni->type->matrix_columns;
1702 const unsigned components = uni->type->vector_elements;
1703
1704 /* Verify that the types are compatible. This is greatly simplified for
1705 * matrices because they can only have a float base type.
1706 */
1707 if (vectors != cols || components != rows) {
1708 _mesa_error(ctx, GL_INVALID_OPERATION,
1709 "glUniformMatrix(matrix size mismatch)");
1710 return;
1711 }
1712
1713 /* Section 2.11.7 (Uniform Variables) of the OpenGL 4.2 Core Profile spec
1714 * says:
1715 *
1716 * "If any of the following conditions occur, an INVALID_OPERATION
1717 * error is generated by the Uniform* commands, and no uniform values
1718 * are changed:
1719 *
1720 * ...
1721 *
1722 * - if the uniform declared in the shader is not of type boolean and
1723 * the type indicated in the name of the Uniform* command used does
1724 * not match the type of the uniform"
1725 *
1726 * There are no Boolean matrix types, so we do not need to allow
1727 * GLSL_TYPE_BOOL here (as _mesa_uniform does).
1728 */
1729 if (uni->type->base_type != basicType &&
1730 !(uni->type->base_type == GLSL_TYPE_FLOAT16 &&
1731 basicType == GLSL_TYPE_FLOAT)) {
1732 _mesa_error(ctx, GL_INVALID_OPERATION,
1733 "glUniformMatrix%ux%u(\"%s\"@%d is %s, not %s)",
1734 cols, rows, uni->name, location,
1735 glsl_type_name(uni->type->base_type),
1736 glsl_type_name(basicType));
1737 return;
1738 }
1739
1740 if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
1741 log_uniform(values, uni->type->base_type, components, vectors, count,
1742 bool(transpose), shProg, location, uni);
1743 }
1744
1745 /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
1746 *
1747 * "When loading N elements starting at an arbitrary position k in a
1748 * uniform declared as an array, elements k through k + N - 1 in the
1749 * array will be replaced with the new values. Values for any array
1750 * element that exceeds the highest array element index used, as
1751 * reported by GetActiveUniform, will be ignored by the GL."
1752 *
1753 * Clamp 'count' to a valid value. Note that for non-arrays a count > 1
1754 * will have already generated an error.
1755 */
1756 if (uni->array_elements != 0) {
1757 count = MIN2(count, (int) (uni->array_elements - offset));
1758 }
1759
1760 /* Store the data in the "actual type" backing storage for the uniform.
1761 */
1762 gl_constant_value *storage;
1763 const unsigned elements = components * vectors;
1764 if (ctx->Const.PackedDriverUniformStorage) {
1765 bool flushed = false;
1766
1767 for (unsigned s = 0; s < uni->num_driver_storage; s++) {
1768 unsigned dword_components = components;
1769
1770 /* 16-bit uniforms are packed. */
1771 if (glsl_base_type_is_16bit(uni->type->base_type))
1772 dword_components = DIV_ROUND_UP(dword_components, 2);
1773
1774 storage = (gl_constant_value *)
1775 uni->driver_storage[s].data +
1776 (size_mul * offset * dword_components * vectors);
1777
1778 if (copy_uniform_matrix_to_storage(ctx, storage, uni, count, values,
1779 size_mul, offset, components,
1780 vectors, transpose, cols, rows,
1781 basicType, !flushed))
1782 flushed = true;
1783 }
1784 } else {
1785 storage = &uni->storage[size_mul * elements * offset];
1786 if (copy_uniform_matrix_to_storage(ctx, storage, uni, count, values,
1787 size_mul, offset, components, vectors,
1788 transpose, cols, rows, basicType,
1789 true))
1790 _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
1791 }
1792 }
1793
1794 static void
update_bound_bindless_sampler_flag(struct gl_program * prog)1795 update_bound_bindless_sampler_flag(struct gl_program *prog)
1796 {
1797 unsigned i;
1798
1799 if (likely(!prog->sh.HasBoundBindlessSampler))
1800 return;
1801
1802 for (i = 0; i < prog->sh.NumBindlessSamplers; i++) {
1803 struct gl_bindless_sampler *sampler = &prog->sh.BindlessSamplers[i];
1804
1805 if (sampler->bound)
1806 return;
1807 }
1808 prog->sh.HasBoundBindlessSampler = false;
1809 }
1810
1811 static void
update_bound_bindless_image_flag(struct gl_program * prog)1812 update_bound_bindless_image_flag(struct gl_program *prog)
1813 {
1814 unsigned i;
1815
1816 if (likely(!prog->sh.HasBoundBindlessImage))
1817 return;
1818
1819 for (i = 0; i < prog->sh.NumBindlessImages; i++) {
1820 struct gl_bindless_image *image = &prog->sh.BindlessImages[i];
1821
1822 if (image->bound)
1823 return;
1824 }
1825 prog->sh.HasBoundBindlessImage = false;
1826 }
1827
1828 /**
1829 * Called via glUniformHandleui64*ARB() functions.
1830 */
1831 extern "C" void
_mesa_uniform_handle(GLint location,GLsizei count,const GLvoid * values,struct gl_context * ctx,struct gl_shader_program * shProg)1832 _mesa_uniform_handle(GLint location, GLsizei count, const GLvoid *values,
1833 struct gl_context *ctx, struct gl_shader_program *shProg)
1834 {
1835 unsigned offset;
1836 struct gl_uniform_storage *uni;
1837
1838 if (_mesa_is_no_error_enabled(ctx)) {
1839 /* From Section 7.6 (UNIFORM VARIABLES) of the OpenGL 4.5 spec:
1840 *
1841 * "If the value of location is -1, the Uniform* commands will
1842 * silently ignore the data passed in, and the current uniform values
1843 * will not be changed.
1844 */
1845 if (location == -1)
1846 return;
1847
1848 uni = shProg->UniformRemapTable[location];
1849 if (!uni || uni == INACTIVE_UNIFORM_EXPLICIT_LOCATION)
1850 return;
1851
1852 /* The array index specified by the uniform location is just the
1853 * uniform location minus the base location of of the uniform.
1854 */
1855 assert(uni->array_elements > 0 || location == (int)uni->remap_location);
1856 offset = location - uni->remap_location;
1857 } else {
1858 uni = validate_uniform_parameters(location, count, &offset,
1859 ctx, shProg, "glUniformHandleui64*ARB");
1860 if (!uni)
1861 return;
1862
1863 if (!uni->is_bindless) {
1864 /* From section "Errors" of the ARB_bindless_texture spec:
1865 *
1866 * "The error INVALID_OPERATION is generated by
1867 * UniformHandleui64{v}ARB if the sampler or image uniform being
1868 * updated has the "bound_sampler" or "bound_image" layout qualifier."
1869 *
1870 * From section 4.4.6 of the ARB_bindless_texture spec:
1871 *
1872 * "In the absence of these qualifiers, sampler and image uniforms are
1873 * considered "bound". Additionally, if GL_ARB_bindless_texture is
1874 * not enabled, these uniforms are considered "bound"."
1875 */
1876 _mesa_error(ctx, GL_INVALID_OPERATION,
1877 "glUniformHandleui64*ARB(non-bindless sampler/image uniform)");
1878 return;
1879 }
1880 }
1881
1882 const unsigned components = uni->type->vector_elements;
1883 const int size_mul = 2;
1884
1885 if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) {
1886 log_uniform(values, GLSL_TYPE_UINT64, components, 1, count,
1887 false, shProg, location, uni);
1888 }
1889
1890 /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
1891 *
1892 * "When loading N elements starting at an arbitrary position k in a
1893 * uniform declared as an array, elements k through k + N - 1 in the
1894 * array will be replaced with the new values. Values for any array
1895 * element that exceeds the highest array element index used, as
1896 * reported by GetActiveUniform, will be ignored by the GL."
1897 *
1898 * Clamp 'count' to a valid value. Note that for non-arrays a count > 1
1899 * will have already generated an error.
1900 */
1901 if (uni->array_elements != 0) {
1902 count = MIN2(count, (int) (uni->array_elements - offset));
1903 }
1904
1905
1906 /* Store the data in the "actual type" backing storage for the uniform.
1907 */
1908 if (ctx->Const.PackedDriverUniformStorage) {
1909 bool flushed = false;
1910
1911 for (unsigned s = 0; s < uni->num_driver_storage; s++) {
1912 void *storage = (gl_constant_value *)
1913 uni->driver_storage[s].data + (size_mul * offset * components);
1914 unsigned size = sizeof(uni->storage[0]) * components * count * size_mul;
1915
1916 if (!memcmp(storage, values, size))
1917 continue;
1918
1919 if (!flushed) {
1920 _mesa_flush_vertices_for_uniforms(ctx, uni);
1921 flushed = true;
1922 }
1923 memcpy(storage, values, size);
1924 }
1925 if (!flushed)
1926 return;
1927 } else {
1928 void *storage = &uni->storage[size_mul * components * offset];
1929 unsigned size = sizeof(uni->storage[0]) * components * count * size_mul;
1930
1931 if (!memcmp(storage, values, size))
1932 return;
1933
1934 _mesa_flush_vertices_for_uniforms(ctx, uni);
1935 memcpy(storage, values, size);
1936 _mesa_propagate_uniforms_to_driver_storage(uni, offset, count);
1937 }
1938
1939 if (uni->type->is_sampler()) {
1940 /* Mark this bindless sampler as not bound to a texture unit because
1941 * it refers to a texture handle.
1942 */
1943 for (int i = 0; i < MESA_SHADER_STAGES; i++) {
1944 struct gl_linked_shader *const sh = shProg->_LinkedShaders[i];
1945
1946 /* If the shader stage doesn't use the sampler uniform, skip this. */
1947 if (!uni->opaque[i].active)
1948 continue;
1949
1950 for (int j = 0; j < count; j++) {
1951 unsigned unit = uni->opaque[i].index + offset + j;
1952 struct gl_bindless_sampler *sampler =
1953 &sh->Program->sh.BindlessSamplers[unit];
1954
1955 sampler->bound = false;
1956 }
1957
1958 update_bound_bindless_sampler_flag(sh->Program);
1959 }
1960 }
1961
1962 if (uni->type->is_image()) {
1963 /* Mark this bindless image as not bound to an image unit because it
1964 * refers to a texture handle.
1965 */
1966 for (int i = 0; i < MESA_SHADER_STAGES; i++) {
1967 struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
1968
1969 /* If the shader stage doesn't use the sampler uniform, skip this. */
1970 if (!uni->opaque[i].active)
1971 continue;
1972
1973 for (int j = 0; j < count; j++) {
1974 unsigned unit = uni->opaque[i].index + offset + j;
1975 struct gl_bindless_image *image =
1976 &sh->Program->sh.BindlessImages[unit];
1977
1978 image->bound = false;
1979 }
1980
1981 update_bound_bindless_image_flag(sh->Program);
1982 }
1983 }
1984 }
1985
1986 extern "C" bool
_mesa_sampler_uniforms_are_valid(const struct gl_shader_program * shProg,char * errMsg,size_t errMsgLength)1987 _mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
1988 char *errMsg, size_t errMsgLength)
1989 {
1990 /* Shader does not have samplers. */
1991 if (shProg->data->NumUniformStorage == 0)
1992 return true;
1993
1994 if (!shProg->SamplersValidated) {
1995 snprintf(errMsg, errMsgLength,
1996 "active samplers with a different type "
1997 "refer to the same texture image unit");
1998 return false;
1999 }
2000 return true;
2001 }
2002
2003 extern "C" bool
_mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object * pipeline)2004 _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline)
2005 {
2006 /* Section 2.11.11 (Shader Execution), subheading "Validation," of the
2007 * OpenGL 4.1 spec says:
2008 *
2009 * "[INVALID_OPERATION] is generated by any command that transfers
2010 * vertices to the GL if:
2011 *
2012 * ...
2013 *
2014 * - Any two active samplers in the current program object are of
2015 * different types, but refer to the same texture image unit.
2016 *
2017 * - The number of active samplers in the program exceeds the
2018 * maximum number of texture image units allowed."
2019 */
2020
2021 GLbitfield mask;
2022 GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
2023 unsigned active_samplers = 0;
2024 const struct gl_program **prog =
2025 (const struct gl_program **) pipeline->CurrentProgram;
2026
2027
2028 memset(TexturesUsed, 0, sizeof(TexturesUsed));
2029
2030 for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
2031 if (!prog[idx])
2032 continue;
2033
2034 mask = prog[idx]->SamplersUsed;
2035 while (mask) {
2036 const int s = u_bit_scan(&mask);
2037 GLuint unit = prog[idx]->SamplerUnits[s];
2038 GLuint tgt = prog[idx]->sh.SamplerTargets[s];
2039
2040 /* FIXME: Samplers are initialized to 0 and Mesa doesn't do a
2041 * great job of eliminating unused uniforms currently so for now
2042 * don't throw an error if two sampler types both point to 0.
2043 */
2044 if (unit == 0)
2045 continue;
2046
2047 if (TexturesUsed[unit] & ~(1 << tgt)) {
2048 pipeline->InfoLog =
2049 ralloc_asprintf(pipeline,
2050 "Program %d: "
2051 "Texture unit %d is accessed with 2 different types",
2052 prog[idx]->Id, unit);
2053 return false;
2054 }
2055
2056 TexturesUsed[unit] |= (1 << tgt);
2057 }
2058
2059 active_samplers += prog[idx]->info.num_textures;
2060 }
2061
2062 if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) {
2063 pipeline->InfoLog =
2064 ralloc_asprintf(pipeline,
2065 "the number of active samplers %d exceed the "
2066 "maximum %d",
2067 active_samplers, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
2068 return false;
2069 }
2070
2071 return true;
2072 }
2073