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