uniform_query.cpp revision af69d88d
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 29#include "main/core.h" 30#include "main/context.h" 31#include "ir.h" 32#include "ir_uniform.h" 33#include "program/hash_table.h" 34#include "../glsl/program.h" 35#include "../glsl/ir_uniform.h" 36#include "../glsl/glsl_parser_extras.h" 37#include "main/shaderapi.h" 38#include "main/shaderobj.h" 39#include "uniforms.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 _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); 50 51 if (!shProg) 52 return; 53 54 if (index >= shProg->NumUserUniformStorage) { 55 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); 56 return; 57 } 58 59 const struct gl_uniform_storage *const uni = &shProg->UniformStorage[index]; 60 61 if (nameOut) { 62 _mesa_get_uniform_name(uni, maxLength, length, nameOut); 63 } 64 65 if (size) { 66 /* array_elements is zero for non-arrays, but the API requires that 1 be 67 * returned. 68 */ 69 *size = MAX2(1, uni->array_elements); 70 } 71 72 if (type) { 73 *type = uni->type->gl_type; 74 } 75} 76 77extern "C" void GLAPIENTRY 78_mesa_GetActiveUniformsiv(GLuint program, 79 GLsizei uniformCount, 80 const GLuint *uniformIndices, 81 GLenum pname, 82 GLint *params) 83{ 84 GET_CURRENT_CONTEXT(ctx); 85 struct gl_shader_program *shProg; 86 GLsizei i; 87 88 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); 89 if (!shProg) 90 return; 91 92 if (uniformCount < 0) { 93 _mesa_error(ctx, GL_INVALID_VALUE, 94 "glGetActiveUniformsiv(uniformCount < 0)"); 95 return; 96 } 97 98 for (i = 0; i < uniformCount; i++) { 99 GLuint index = uniformIndices[i]; 100 101 if (index >= shProg->NumUserUniformStorage) { 102 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)"); 103 return; 104 } 105 } 106 107 for (i = 0; i < uniformCount; i++) { 108 GLuint index = uniformIndices[i]; 109 const struct gl_uniform_storage *uni = &shProg->UniformStorage[index]; 110 111 switch (pname) { 112 case GL_UNIFORM_TYPE: 113 params[i] = uni->type->gl_type; 114 break; 115 116 case GL_UNIFORM_SIZE: 117 /* array_elements is zero for non-arrays, but the API requires that 1 be 118 * returned. 119 */ 120 params[i] = MAX2(1, uni->array_elements); 121 break; 122 123 case GL_UNIFORM_NAME_LENGTH: 124 params[i] = strlen(uni->name) + 1; 125 126 /* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0 127 * spec says: 128 * 129 * "If the active uniform is an array, the uniform name returned 130 * in name will always be the name of the uniform array appended 131 * with "[0]"." 132 */ 133 if (uni->array_elements != 0) 134 params[i] += 3; 135 break; 136 137 case GL_UNIFORM_BLOCK_INDEX: 138 params[i] = uni->block_index; 139 break; 140 141 case GL_UNIFORM_OFFSET: 142 params[i] = uni->offset; 143 break; 144 145 case GL_UNIFORM_ARRAY_STRIDE: 146 params[i] = uni->array_stride; 147 break; 148 149 case GL_UNIFORM_MATRIX_STRIDE: 150 params[i] = uni->matrix_stride; 151 break; 152 153 case GL_UNIFORM_IS_ROW_MAJOR: 154 params[i] = uni->row_major; 155 break; 156 157 case GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX: 158 if (!ctx->Extensions.ARB_shader_atomic_counters) 159 goto invalid_enum; 160 params[i] = uni->atomic_buffer_index; 161 break; 162 163 default: 164 goto invalid_enum; 165 } 166 } 167 168 return; 169 170 invalid_enum: 171 _mesa_error(ctx, GL_INVALID_ENUM, "glGetActiveUniformsiv(pname)"); 172} 173 174static struct gl_uniform_storage * 175validate_uniform_parameters(struct gl_context *ctx, 176 struct gl_shader_program *shProg, 177 GLint location, GLsizei count, 178 unsigned *array_index, 179 const char *caller, 180 bool negative_one_is_not_valid) 181{ 182 if (!shProg || !shProg->LinkStatus) { 183 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", caller); 184 return NULL; 185 } 186 187 if (location == -1) { 188 /* For glGetUniform, page 264 (page 278 of the PDF) of the OpenGL 2.1 189 * spec says: 190 * 191 * "The error INVALID_OPERATION is generated if program has not been 192 * linked successfully, or if location is not a valid location for 193 * program." 194 * 195 * For glUniform, page 82 (page 96 of the PDF) of the OpenGL 2.1 spec 196 * says: 197 * 198 * "If the value of location is -1, the Uniform* commands will 199 * silently ignore the data passed in, and the current uniform 200 * values will not be changed." 201 * 202 * Allowing -1 for the location parameter of glUniform allows 203 * applications to avoid error paths in the case that, for example, some 204 * uniform variable is removed by the compiler / linker after 205 * optimization. In this case, the new value of the uniform is dropped 206 * on the floor. For the case of glGetUniform, there is nothing 207 * sensible to do for a location of -1. 208 * 209 * The negative_one_is_not_valid flag selects between the two behaviors. 210 */ 211 if (negative_one_is_not_valid) { 212 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 213 caller, location); 214 } 215 216 return NULL; 217 } 218 219 /* From page 12 (page 26 of the PDF) of the OpenGL 2.1 spec: 220 * 221 * "If a negative number is provided where an argument of type sizei or 222 * sizeiptr is specified, the error INVALID_VALUE is generated." 223 */ 224 if (count < 0) { 225 _mesa_error(ctx, GL_INVALID_VALUE, "%s(count < 0)", caller); 226 return NULL; 227 } 228 229 /* Check that the given location is in bounds of uniform remap table. */ 230 if (location >= (GLint) shProg->NumUniformRemapTable) { 231 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 232 caller, location); 233 return NULL; 234 } 235 236 /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: 237 * 238 * "If any of the following conditions occur, an INVALID_OPERATION 239 * error is generated by the Uniform* commands, and no uniform values 240 * are changed: 241 * 242 * ... 243 * 244 * - if no variable with a location of location exists in the 245 * program object currently in use and location is not -1, 246 * - if count is greater than one, and the uniform declared in the 247 * shader is not an array variable, 248 */ 249 if (location < -1 || !shProg->UniformRemapTable[location]) { 250 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 251 caller, location); 252 return NULL; 253 } 254 255 /* If the driver storage pointer in remap table is -1, we ignore silently. 256 * 257 * GL_ARB_explicit_uniform_location spec says: 258 * "What happens if Uniform* is called with an explicitly defined 259 * uniform location, but that uniform is deemed inactive by the 260 * linker? 261 * 262 * RESOLVED: The call is ignored for inactive uniform variables and 263 * no error is generated." 264 * 265 */ 266 if (shProg->UniformRemapTable[location] == 267 INACTIVE_UNIFORM_EXPLICIT_LOCATION) 268 return NULL; 269 270 struct gl_uniform_storage *const uni = shProg->UniformRemapTable[location]; 271 272 if (uni->array_elements == 0 && count > 1) { 273 _mesa_error(ctx, GL_INVALID_OPERATION, 274 "%s(count > 1 for non-array, location=%d)", 275 caller, location); 276 return NULL; 277 } 278 279 /* The array index specified by the uniform location is just the uniform 280 * location minus the base location of of the uniform. 281 */ 282 *array_index = location - uni->remap_location; 283 284 /* If the uniform is an array, check that array_index is in bounds. 285 * If not an array, check that array_index is zero. 286 * array_index is unsigned so no need to check for less than zero. 287 */ 288 const unsigned limit = MAX2(uni->array_elements, 1); 289 if (*array_index >= limit) { 290 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 291 caller, location); 292 return NULL; 293 } 294 return uni; 295} 296 297/** 298 * Called via glGetUniform[fiui]v() to get the current value of a uniform. 299 */ 300extern "C" void 301_mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, 302 GLsizei bufSize, enum glsl_base_type returnType, 303 GLvoid *paramsOut) 304{ 305 struct gl_shader_program *shProg = 306 _mesa_lookup_shader_program_err(ctx, program, "glGetUniformfv"); 307 unsigned offset; 308 309 struct gl_uniform_storage *const uni = 310 validate_uniform_parameters(ctx, shProg, location, 1, 311 &offset, "glGetUniform", true); 312 if (uni == NULL) 313 return; 314 315 { 316 unsigned elements = (uni->type->is_sampler()) 317 ? 1 : uni->type->components(); 318 319 /* Calculate the source base address *BEFORE* modifying elements to 320 * account for the size of the user's buffer. 321 */ 322 const union gl_constant_value *const src = 323 &uni->storage[offset * elements]; 324 325 assert(returnType == GLSL_TYPE_FLOAT || returnType == GLSL_TYPE_INT || 326 returnType == GLSL_TYPE_UINT); 327 /* The three (currently) supported types all have the same size, 328 * which is of course the same as their union. That'll change 329 * with glGetUniformdv()... 330 */ 331 unsigned bytes = sizeof(src[0]) * elements; 332 if (bufSize < 0 || bytes > (unsigned) bufSize) { 333 _mesa_error( ctx, GL_INVALID_OPERATION, 334 "glGetnUniform*vARB(out of bounds: bufSize is %d," 335 " but %u bytes are required)", bufSize, bytes ); 336 return; 337 } 338 339 /* If the return type and the uniform's native type are "compatible," 340 * just memcpy the data. If the types are not compatible, perform a 341 * slower convert-and-copy process. 342 */ 343 if (returnType == uni->type->base_type 344 || ((returnType == GLSL_TYPE_INT 345 || returnType == GLSL_TYPE_UINT 346 || returnType == GLSL_TYPE_SAMPLER) 347 && 348 (uni->type->base_type == GLSL_TYPE_INT 349 || uni->type->base_type == GLSL_TYPE_UINT 350 || uni->type->base_type == GLSL_TYPE_SAMPLER))) { 351 memcpy(paramsOut, src, bytes); 352 } else { 353 union gl_constant_value *const dst = 354 (union gl_constant_value *) paramsOut; 355 356 /* This code could be optimized by putting the loop inside the switch 357 * statements. However, this is not expected to be 358 * performance-critical code. 359 */ 360 for (unsigned i = 0; i < elements; i++) { 361 switch (returnType) { 362 case GLSL_TYPE_FLOAT: 363 switch (uni->type->base_type) { 364 case GLSL_TYPE_UINT: 365 dst[i].f = (float) src[i].u; 366 break; 367 case GLSL_TYPE_INT: 368 case GLSL_TYPE_SAMPLER: 369 dst[i].f = (float) src[i].i; 370 break; 371 case GLSL_TYPE_BOOL: 372 dst[i].f = src[i].i ? 1.0f : 0.0f; 373 break; 374 default: 375 assert(!"Should not get here."); 376 break; 377 } 378 break; 379 380 case GLSL_TYPE_INT: 381 case GLSL_TYPE_UINT: 382 switch (uni->type->base_type) { 383 case GLSL_TYPE_FLOAT: 384 /* While the GL 3.2 core spec doesn't explicitly 385 * state how conversion of float uniforms to integer 386 * values works, in section 6.2 "State Tables" on 387 * page 267 it says: 388 * 389 * "Unless otherwise specified, when floating 390 * point state is returned as integer values or 391 * integer state is returned as floating-point 392 * values it is converted in the fashion 393 * described in section 6.1.2" 394 * 395 * That section, on page 248, says: 396 * 397 * "If GetIntegerv or GetInteger64v are called, 398 * a floating-point value is rounded to the 399 * nearest integer..." 400 */ 401 dst[i].i = IROUND(src[i].f); 402 break; 403 case GLSL_TYPE_BOOL: 404 dst[i].i = src[i].i ? 1 : 0; 405 break; 406 default: 407 assert(!"Should not get here."); 408 break; 409 } 410 break; 411 412 default: 413 assert(!"Should not get here."); 414 break; 415 } 416 } 417 } 418 } 419} 420 421static void 422log_uniform(const void *values, enum glsl_base_type basicType, 423 unsigned rows, unsigned cols, unsigned count, 424 bool transpose, 425 const struct gl_shader_program *shProg, 426 GLint location, 427 const struct gl_uniform_storage *uni) 428{ 429 430 const union gl_constant_value *v = (const union gl_constant_value *) values; 431 const unsigned elems = rows * cols * count; 432 const char *const extra = (cols == 1) ? "uniform" : "uniform matrix"; 433 434 printf("Mesa: set program %u %s \"%s\" (loc %d, type \"%s\", " 435 "transpose = %s) to: ", 436 shProg->Name, extra, uni->name, location, uni->type->name, 437 transpose ? "true" : "false"); 438 for (unsigned i = 0; i < elems; i++) { 439 if (i != 0 && ((i % rows) == 0)) 440 printf(", "); 441 442 switch (basicType) { 443 case GLSL_TYPE_UINT: 444 printf("%u ", v[i].u); 445 break; 446 case GLSL_TYPE_INT: 447 printf("%d ", v[i].i); 448 break; 449 case GLSL_TYPE_FLOAT: 450 printf("%g ", v[i].f); 451 break; 452 default: 453 assert(!"Should not get here."); 454 break; 455 } 456 } 457 printf("\n"); 458 fflush(stdout); 459} 460 461#if 0 462static void 463log_program_parameters(const struct gl_shader_program *shProg) 464{ 465 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 466 if (shProg->_LinkedShaders[i] == NULL) 467 continue; 468 469 const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program; 470 471 printf("Program %d %s shader parameters:\n", 472 shProg->Name, _mesa_shader_stage_to_string(i)); 473 for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) { 474 printf("%s: %p %f %f %f %f\n", 475 prog->Parameters->Parameters[j].Name, 476 prog->Parameters->ParameterValues[j], 477 prog->Parameters->ParameterValues[j][0].f, 478 prog->Parameters->ParameterValues[j][1].f, 479 prog->Parameters->ParameterValues[j][2].f, 480 prog->Parameters->ParameterValues[j][3].f); 481 } 482 } 483 fflush(stdout); 484} 485#endif 486 487/** 488 * Propagate some values from uniform backing storage to driver storage 489 * 490 * Values propagated from uniform backing storage to driver storage 491 * have all format / type conversions previously requested by the 492 * driver applied. This function is most often called by the 493 * implementations of \c glUniform1f, etc. and \c glUniformMatrix2f, 494 * etc. 495 * 496 * \param uni Uniform whose data is to be propagated to driver storage 497 * \param array_index If \c uni is an array, this is the element of 498 * the array to be propagated. 499 * \param count Number of array elements to propagate. 500 */ 501extern "C" void 502_mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni, 503 unsigned array_index, 504 unsigned count) 505{ 506 unsigned i; 507 508 /* vector_elements and matrix_columns can be 0 for samplers. 509 */ 510 const unsigned components = MAX2(1, uni->type->vector_elements); 511 const unsigned vectors = MAX2(1, uni->type->matrix_columns); 512 513 /* Store the data in the driver's requested type in the driver's storage 514 * areas. 515 */ 516 unsigned src_vector_byte_stride = components * 4; 517 518 for (i = 0; i < uni->num_driver_storage; i++) { 519 struct gl_uniform_driver_storage *const store = &uni->driver_storage[i]; 520 uint8_t *dst = (uint8_t *) store->data; 521 const unsigned extra_stride = 522 store->element_stride - (vectors * store->vector_stride); 523 const uint8_t *src = 524 (uint8_t *) (&uni->storage[array_index * (components * vectors)].i); 525 526#if 0 527 printf("%s: %p[%d] components=%u vectors=%u count=%u vector_stride=%u " 528 "extra_stride=%u\n", 529 __func__, dst, array_index, components, 530 vectors, count, store->vector_stride, extra_stride); 531#endif 532 533 dst += array_index * store->element_stride; 534 535 switch (store->format) { 536 case uniform_native: 537 case uniform_bool_int_0_1: { 538 unsigned j; 539 unsigned v; 540 541 for (j = 0; j < count; j++) { 542 for (v = 0; v < vectors; v++) { 543 memcpy(dst, src, src_vector_byte_stride); 544 src += src_vector_byte_stride; 545 dst += store->vector_stride; 546 } 547 548 dst += extra_stride; 549 } 550 break; 551 } 552 553 case uniform_int_float: 554 case uniform_bool_float: { 555 const int *isrc = (const int *) src; 556 unsigned j; 557 unsigned v; 558 unsigned c; 559 560 for (j = 0; j < count; j++) { 561 for (v = 0; v < vectors; v++) { 562 for (c = 0; c < components; c++) { 563 ((float *) dst)[c] = (float) *isrc; 564 isrc++; 565 } 566 567 dst += store->vector_stride; 568 } 569 570 dst += extra_stride; 571 } 572 break; 573 } 574 575 case uniform_bool_int_0_not0: { 576 const int *isrc = (const int *) src; 577 unsigned j; 578 unsigned v; 579 unsigned c; 580 581 for (j = 0; j < count; j++) { 582 for (v = 0; v < vectors; v++) { 583 for (c = 0; c < components; c++) { 584 ((int *) dst)[c] = *isrc == 0 ? 0 : ~0; 585 isrc++; 586 } 587 588 dst += store->vector_stride; 589 } 590 591 dst += extra_stride; 592 } 593 break; 594 } 595 596 default: 597 assert(!"Should not get here."); 598 break; 599 } 600 } 601} 602 603/** 604 * Called via glUniform*() functions. 605 */ 606extern "C" void 607_mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, 608 GLint location, GLsizei count, 609 const GLvoid *values, GLenum type) 610{ 611 unsigned offset; 612 unsigned components; 613 unsigned src_components; 614 enum glsl_base_type basicType; 615 616 struct gl_uniform_storage *const uni = 617 validate_uniform_parameters(ctx, shProg, location, count, 618 &offset, "glUniform", false); 619 if (uni == NULL) 620 return; 621 622 /* Verify that the types are compatible. 623 */ 624 switch (type) { 625 case GL_FLOAT: 626 basicType = GLSL_TYPE_FLOAT; 627 src_components = 1; 628 break; 629 case GL_FLOAT_VEC2: 630 basicType = GLSL_TYPE_FLOAT; 631 src_components = 2; 632 break; 633 case GL_FLOAT_VEC3: 634 basicType = GLSL_TYPE_FLOAT; 635 src_components = 3; 636 break; 637 case GL_FLOAT_VEC4: 638 basicType = GLSL_TYPE_FLOAT; 639 src_components = 4; 640 break; 641 case GL_UNSIGNED_INT: 642 basicType = GLSL_TYPE_UINT; 643 src_components = 1; 644 break; 645 case GL_UNSIGNED_INT_VEC2: 646 basicType = GLSL_TYPE_UINT; 647 src_components = 2; 648 break; 649 case GL_UNSIGNED_INT_VEC3: 650 basicType = GLSL_TYPE_UINT; 651 src_components = 3; 652 break; 653 case GL_UNSIGNED_INT_VEC4: 654 basicType = GLSL_TYPE_UINT; 655 src_components = 4; 656 break; 657 case GL_INT: 658 basicType = GLSL_TYPE_INT; 659 src_components = 1; 660 break; 661 case GL_INT_VEC2: 662 basicType = GLSL_TYPE_INT; 663 src_components = 2; 664 break; 665 case GL_INT_VEC3: 666 basicType = GLSL_TYPE_INT; 667 src_components = 3; 668 break; 669 case GL_INT_VEC4: 670 basicType = GLSL_TYPE_INT; 671 src_components = 4; 672 break; 673 case GL_BOOL: 674 case GL_BOOL_VEC2: 675 case GL_BOOL_VEC3: 676 case GL_BOOL_VEC4: 677 case GL_FLOAT_MAT2: 678 case GL_FLOAT_MAT2x3: 679 case GL_FLOAT_MAT2x4: 680 case GL_FLOAT_MAT3x2: 681 case GL_FLOAT_MAT3: 682 case GL_FLOAT_MAT3x4: 683 case GL_FLOAT_MAT4x2: 684 case GL_FLOAT_MAT4x3: 685 case GL_FLOAT_MAT4: 686 default: 687 _mesa_problem(NULL, "Invalid type in %s", __func__); 688 return; 689 } 690 691 if (uni->type->is_sampler()) { 692 components = 1; 693 } else { 694 components = uni->type->vector_elements; 695 } 696 697 bool match; 698 switch (uni->type->base_type) { 699 case GLSL_TYPE_BOOL: 700 match = true; 701 break; 702 case GLSL_TYPE_SAMPLER: 703 case GLSL_TYPE_IMAGE: 704 match = (basicType == GLSL_TYPE_INT); 705 break; 706 default: 707 match = (basicType == uni->type->base_type); 708 break; 709 } 710 711 if (uni->type->is_matrix() || components != src_components || !match) { 712 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)"); 713 return; 714 } 715 716 if (ctx->_Shader->Flags & GLSL_UNIFORMS) { 717 log_uniform(values, basicType, components, 1, count, 718 false, shProg, location, uni); 719 } 720 721 /* Page 100 (page 116 of the PDF) of the OpenGL 3.0 spec says: 722 * 723 * "Setting a sampler's value to i selects texture image unit number 724 * i. The values of i range from zero to the implementation- dependent 725 * maximum supported number of texture image units." 726 * 727 * In addition, table 2.3, "Summary of GL errors," on page 17 (page 33 of 728 * the PDF) says: 729 * 730 * "Error Description Offending command 731 * ignored? 732 * ... 733 * INVALID_VALUE Numeric argument out of range Yes" 734 * 735 * Based on that, when an invalid sampler is specified, we generate a 736 * GL_INVALID_VALUE error and ignore the command. 737 */ 738 if (uni->type->is_sampler()) { 739 int i; 740 741 for (i = 0; i < count; i++) { 742 const unsigned texUnit = ((unsigned *) values)[i]; 743 744 /* check that the sampler (tex unit index) is legal */ 745 if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) { 746 _mesa_error(ctx, GL_INVALID_VALUE, 747 "glUniform1i(invalid sampler/tex unit index for " 748 "uniform %d)", 749 location); 750 return; 751 } 752 } 753 } 754 755 if (uni->type->is_image()) { 756 int i; 757 758 for (i = 0; i < count; i++) { 759 const int unit = ((GLint *) values)[i]; 760 761 /* check that the image unit is legal */ 762 if (unit < 0 || unit >= (int)ctx->Const.MaxImageUnits) { 763 _mesa_error(ctx, GL_INVALID_VALUE, 764 "glUniform1i(invalid image unit index for uniform %d)", 765 location); 766 return; 767 } 768 } 769 } 770 771 /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: 772 * 773 * "When loading N elements starting at an arbitrary position k in a 774 * uniform declared as an array, elements k through k + N - 1 in the 775 * array will be replaced with the new values. Values for any array 776 * element that exceeds the highest array element index used, as 777 * reported by GetActiveUniform, will be ignored by the GL." 778 * 779 * Clamp 'count' to a valid value. Note that for non-arrays a count > 1 780 * will have already generated an error. 781 */ 782 if (uni->array_elements != 0) { 783 count = MIN2(count, (int) (uni->array_elements - offset)); 784 } 785 786 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); 787 788 /* Store the data in the "actual type" backing storage for the uniform. 789 */ 790 if (!uni->type->is_boolean()) { 791 memcpy(&uni->storage[components * offset], values, 792 sizeof(uni->storage[0]) * components * count); 793 } else { 794 const union gl_constant_value *src = 795 (const union gl_constant_value *) values; 796 union gl_constant_value *dst = &uni->storage[components * offset]; 797 const unsigned elems = components * count; 798 unsigned i; 799 800 for (i = 0; i < elems; i++) { 801 if (basicType == GLSL_TYPE_FLOAT) { 802 dst[i].i = src[i].f != 0.0f ? ctx->Const.UniformBooleanTrue : 0; 803 } else { 804 dst[i].i = src[i].i != 0 ? ctx->Const.UniformBooleanTrue : 0; 805 } 806 } 807 } 808 809 uni->initialized = true; 810 811 _mesa_propagate_uniforms_to_driver_storage(uni, offset, count); 812 813 /* If the uniform is a sampler, do the extra magic necessary to propagate 814 * the changes through. 815 */ 816 if (uni->type->is_sampler()) { 817 int i; 818 819 bool flushed = false; 820 for (i = 0; i < MESA_SHADER_STAGES; i++) { 821 struct gl_shader *const sh = shProg->_LinkedShaders[i]; 822 int j; 823 824 /* If the shader stage doesn't use the sampler uniform, skip this. 825 */ 826 if (sh == NULL || !uni->sampler[i].active) 827 continue; 828 829 for (j = 0; j < count; j++) { 830 sh->SamplerUnits[uni->sampler[i].index + offset + j] = 831 ((unsigned *) values)[j]; 832 } 833 834 struct gl_program *const prog = sh->Program; 835 836 assert(sizeof(prog->SamplerUnits) == sizeof(sh->SamplerUnits)); 837 838 /* Determine if any of the samplers used by this shader stage have 839 * been modified. 840 */ 841 bool changed = false; 842 for (unsigned j = 0; j < Elements(prog->SamplerUnits); j++) { 843 if ((sh->active_samplers & (1U << j)) != 0 844 && (prog->SamplerUnits[j] != sh->SamplerUnits[j])) { 845 changed = true; 846 break; 847 } 848 } 849 850 if (changed) { 851 if (!flushed) { 852 FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM); 853 flushed = true; 854 } 855 856 memcpy(prog->SamplerUnits, 857 sh->SamplerUnits, 858 sizeof(sh->SamplerUnits)); 859 860 _mesa_update_shader_textures_used(shProg, prog); 861 if (ctx->Driver.SamplerUniformChange) 862 ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog); 863 } 864 } 865 } 866 867 /* If the uniform is an image, update the mapping from image 868 * uniforms to image units present in the shader data structure. 869 */ 870 if (uni->type->is_image()) { 871 int i, j; 872 873 for (i = 0; i < MESA_SHADER_STAGES; i++) { 874 if (uni->image[i].active) { 875 struct gl_shader *sh = shProg->_LinkedShaders[i]; 876 877 for (j = 0; j < count; j++) 878 sh->ImageUnits[uni->image[i].index + offset + j] = 879 ((GLint *) values)[j]; 880 } 881 } 882 883 ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; 884 } 885} 886 887/** 888 * Called by glUniformMatrix*() functions. 889 * Note: cols=2, rows=4 ==> array[2] of vec4 890 */ 891extern "C" void 892_mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, 893 GLuint cols, GLuint rows, 894 GLint location, GLsizei count, 895 GLboolean transpose, const GLfloat *values) 896{ 897 unsigned offset; 898 unsigned vectors; 899 unsigned components; 900 unsigned elements; 901 902 struct gl_uniform_storage *const uni = 903 validate_uniform_parameters(ctx, shProg, location, count, 904 &offset, "glUniformMatrix", false); 905 if (uni == NULL) 906 return; 907 908 if (!uni->type->is_matrix()) { 909 _mesa_error(ctx, GL_INVALID_OPERATION, 910 "glUniformMatrix(non-matrix uniform)"); 911 return; 912 } 913 914 assert(!uni->type->is_sampler()); 915 vectors = uni->type->matrix_columns; 916 components = uni->type->vector_elements; 917 918 /* Verify that the types are compatible. This is greatly simplified for 919 * matrices because they can only have a float base type. 920 */ 921 if (vectors != cols || components != rows) { 922 _mesa_error(ctx, GL_INVALID_OPERATION, 923 "glUniformMatrix(matrix size mismatch)"); 924 return; 925 } 926 927 /* GL_INVALID_VALUE is generated if `transpose' is not GL_FALSE. 928 * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml */ 929 if (ctx->API == API_OPENGLES 930 || (ctx->API == API_OPENGLES2 && ctx->Version < 30)) { 931 if (transpose) { 932 _mesa_error(ctx, GL_INVALID_VALUE, 933 "glUniformMatrix(matrix transpose is not GL_FALSE)"); 934 return; 935 } 936 } 937 938 if (ctx->_Shader->Flags & GLSL_UNIFORMS) { 939 log_uniform(values, GLSL_TYPE_FLOAT, components, vectors, count, 940 bool(transpose), shProg, location, uni); 941 } 942 943 /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: 944 * 945 * "When loading N elements starting at an arbitrary position k in a 946 * uniform declared as an array, elements k through k + N - 1 in the 947 * array will be replaced with the new values. Values for any array 948 * element that exceeds the highest array element index used, as 949 * reported by GetActiveUniform, will be ignored by the GL." 950 * 951 * Clamp 'count' to a valid value. Note that for non-arrays a count > 1 952 * will have already generated an error. 953 */ 954 if (uni->array_elements != 0) { 955 count = MIN2(count, (int) (uni->array_elements - offset)); 956 } 957 958 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); 959 960 /* Store the data in the "actual type" backing storage for the uniform. 961 */ 962 elements = components * vectors; 963 964 if (!transpose) { 965 memcpy(&uni->storage[elements * offset], values, 966 sizeof(uni->storage[0]) * elements * count); 967 } else { 968 /* Copy and transpose the matrix. 969 */ 970 const float *src = values; 971 float *dst = &uni->storage[elements * offset].f; 972 973 for (int i = 0; i < count; i++) { 974 for (unsigned r = 0; r < rows; r++) { 975 for (unsigned c = 0; c < cols; c++) { 976 dst[(c * components) + r] = src[c + (r * vectors)]; 977 } 978 } 979 980 dst += elements; 981 src += elements; 982 } 983 } 984 985 uni->initialized = true; 986 987 _mesa_propagate_uniforms_to_driver_storage(uni, offset, count); 988} 989 990 991/** 992 * Called via glGetUniformLocation(). 993 * 994 * Returns the uniform index into UniformStorage (also the 995 * glGetActiveUniformsiv uniform index), and stores the referenced 996 * array offset in *offset, or GL_INVALID_INDEX (-1). 997 */ 998extern "C" unsigned 999_mesa_get_uniform_location(struct gl_context *ctx, 1000 struct gl_shader_program *shProg, 1001 const GLchar *name, 1002 unsigned *out_offset) 1003{ 1004 /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says: 1005 * 1006 * "The first element of a uniform array is identified using the 1007 * name of the uniform array appended with "[0]". Except if the last 1008 * part of the string name indicates a uniform array, then the 1009 * location of the first element of that array can be retrieved by 1010 * either using the name of the uniform array, or the name of the 1011 * uniform array appended with "[0]"." 1012 * 1013 * Note: since uniform names are not allowed to use whitespace, and array 1014 * indices within uniform names are not allowed to use "+", "-", or leading 1015 * zeros, it follows that each uniform has a unique name up to the possible 1016 * ambiguity with "[0]" noted above. Therefore we don't need to worry 1017 * about mal-formed inputs--they will properly fail when we try to look up 1018 * the uniform name in shProg->UniformHash. 1019 */ 1020 1021 const GLchar *base_name_end; 1022 long offset = parse_program_resource_name(name, &base_name_end); 1023 bool array_lookup = offset >= 0; 1024 char *name_copy; 1025 1026 if (array_lookup) { 1027 name_copy = (char *) malloc(base_name_end - name + 1); 1028 memcpy(name_copy, name, base_name_end - name); 1029 name_copy[base_name_end - name] = '\0'; 1030 } else { 1031 name_copy = (char *) name; 1032 offset = 0; 1033 } 1034 1035 unsigned location = 0; 1036 const bool found = shProg->UniformHash->get(location, name_copy); 1037 1038 assert(!found 1039 || strcmp(name_copy, shProg->UniformStorage[location].name) == 0); 1040 1041 /* Free the temporary buffer *before* possibly returning an error. 1042 */ 1043 if (name_copy != name) 1044 free(name_copy); 1045 1046 if (!found) 1047 return GL_INVALID_INDEX; 1048 1049 /* If the uniform is an array, fail if the index is out of bounds. 1050 * (A negative index is caught above.) This also fails if the uniform 1051 * is not an array, but the user is trying to index it, because 1052 * array_elements is zero and offset >= 0. 1053 */ 1054 if (array_lookup 1055 && offset >= (long) shProg->UniformStorage[location].array_elements) { 1056 return GL_INVALID_INDEX; 1057 } 1058 1059 *out_offset = offset; 1060 return location; 1061} 1062 1063extern "C" bool 1064_mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg, 1065 char *errMsg, size_t errMsgLength) 1066{ 1067 const glsl_type *unit_types[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; 1068 1069 memset(unit_types, 0, sizeof(unit_types)); 1070 1071 for (unsigned i = 0; i < shProg->NumUserUniformStorage; i++) { 1072 const struct gl_uniform_storage *const storage = 1073 &shProg->UniformStorage[i]; 1074 const glsl_type *const t = (storage->type->is_array()) 1075 ? storage->type->fields.array : storage->type; 1076 1077 if (!t->is_sampler()) 1078 continue; 1079 1080 const unsigned count = MAX2(1, storage->type->array_size()); 1081 for (unsigned j = 0; j < count; j++) { 1082 const unsigned unit = storage->storage[j].i; 1083 1084 /* The types of the samplers associated with a particular texture 1085 * unit must be an exact match. Page 74 (page 89 of the PDF) of the 1086 * OpenGL 3.3 core spec says: 1087 * 1088 * "It is not allowed to have variables of different sampler 1089 * types pointing to the same texture image unit within a program 1090 * object." 1091 */ 1092 if (unit_types[unit] == NULL) { 1093 unit_types[unit] = t; 1094 } else if (unit_types[unit] != t) { 1095 _mesa_snprintf(errMsg, errMsgLength, 1096 "Texture unit %d is accessed both as %s and %s", 1097 unit, unit_types[unit]->name, t->name); 1098 return false; 1099 } 1100 } 1101 } 1102 1103 return true; 1104} 1105 1106extern "C" bool 1107_mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline) 1108{ 1109 /* Section 2.11.11 (Shader Execution), subheading "Validation," of the 1110 * OpenGL 4.1 spec says: 1111 * 1112 * "[INVALID_OPERATION] is generated by any command that transfers 1113 * vertices to the GL if: 1114 * 1115 * ... 1116 * 1117 * - Any two active samplers in the current program object are of 1118 * different types, but refer to the same texture image unit. 1119 * 1120 * - The number of active samplers in the program exceeds the 1121 * maximum number of texture image units allowed." 1122 */ 1123 unsigned active_samplers = 0; 1124 const struct gl_shader_program **shProg = 1125 (const struct gl_shader_program **) pipeline->CurrentProgram; 1126 1127 const glsl_type *unit_types[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; 1128 memset(unit_types, 0, sizeof(unit_types)); 1129 1130 for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) { 1131 if (!shProg[idx]) 1132 continue; 1133 1134 for (unsigned i = 0; i < shProg[idx]->NumUserUniformStorage; i++) { 1135 const struct gl_uniform_storage *const storage = 1136 &shProg[idx]->UniformStorage[i]; 1137 const glsl_type *const t = (storage->type->is_array()) 1138 ? storage->type->fields.array : storage->type; 1139 1140 if (!t->is_sampler()) 1141 continue; 1142 1143 active_samplers++; 1144 1145 const unsigned count = MAX2(1, storage->type->array_size()); 1146 for (unsigned j = 0; j < count; j++) { 1147 const unsigned unit = storage->storage[j].i; 1148 1149 /* The types of the samplers associated with a particular texture 1150 * unit must be an exact match. Page 74 (page 89 of the PDF) of 1151 * the OpenGL 3.3 core spec says: 1152 * 1153 * "It is not allowed to have variables of different sampler 1154 * types pointing to the same texture image unit within a 1155 * program object." 1156 */ 1157 if (unit_types[unit] == NULL) { 1158 unit_types[unit] = t; 1159 } else if (unit_types[unit] != t) { 1160 pipeline->InfoLog = 1161 ralloc_asprintf(pipeline, 1162 "Texture unit %d is accessed both as %s " 1163 "and %s", 1164 unit, unit_types[unit]->name, t->name); 1165 return false; 1166 } 1167 } 1168 } 1169 } 1170 1171 if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) { 1172 pipeline->InfoLog = 1173 ralloc_asprintf(pipeline, 1174 "the number of active samplers %d exceed the " 1175 "maximum %d", 1176 active_samplers, MAX_COMBINED_TEXTURE_IMAGE_UNITS); 1177 return false; 1178 } 1179 1180 return true; 1181} 1182