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