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