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