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