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