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