uniform_query.cpp revision 719909698c67c287a393d2380278e7b7495ae018
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#include <stdlib.h> 26#include "main/core.h" 27#include "main/context.h" 28#include "ir.h" 29#include "ir_uniform.h" 30#include "program/hash_table.h" 31#include "../glsl/program.h" 32#include "../glsl/ir_uniform.h" 33 34extern "C" { 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 GLenum 76base_uniform_type(GLenum type) 77{ 78 switch (type) { 79 case GL_BOOL: 80 case GL_BOOL_VEC2: 81 case GL_BOOL_VEC3: 82 case GL_BOOL_VEC4: 83 return GL_BOOL; 84 case GL_FLOAT: 85 case GL_FLOAT_VEC2: 86 case GL_FLOAT_VEC3: 87 case GL_FLOAT_VEC4: 88 case GL_FLOAT_MAT2: 89 case GL_FLOAT_MAT2x3: 90 case GL_FLOAT_MAT2x4: 91 case GL_FLOAT_MAT3x2: 92 case GL_FLOAT_MAT3: 93 case GL_FLOAT_MAT3x4: 94 case GL_FLOAT_MAT4x2: 95 case GL_FLOAT_MAT4x3: 96 case GL_FLOAT_MAT4: 97 return GL_FLOAT; 98 case GL_UNSIGNED_INT: 99 case GL_UNSIGNED_INT_VEC2: 100 case GL_UNSIGNED_INT_VEC3: 101 case GL_UNSIGNED_INT_VEC4: 102 return GL_UNSIGNED_INT; 103 case GL_INT: 104 case GL_INT_VEC2: 105 case GL_INT_VEC3: 106 case GL_INT_VEC4: 107 return GL_INT; 108 default: 109 _mesa_problem(NULL, "Invalid type in base_uniform_type()"); 110 return GL_FLOAT; 111 } 112} 113 114static GLboolean 115is_boolean_type(GLenum type) 116{ 117 switch (type) { 118 case GL_BOOL: 119 case GL_BOOL_VEC2: 120 case GL_BOOL_VEC3: 121 case GL_BOOL_VEC4: 122 return GL_TRUE; 123 default: 124 return GL_FALSE; 125 } 126} 127 128static GLboolean 129is_sampler_type(GLenum type) 130{ 131 switch (type) { 132 case GL_SAMPLER_1D: 133 case GL_INT_SAMPLER_1D: 134 case GL_UNSIGNED_INT_SAMPLER_1D: 135 case GL_SAMPLER_2D: 136 case GL_INT_SAMPLER_2D: 137 case GL_UNSIGNED_INT_SAMPLER_2D: 138 case GL_SAMPLER_3D: 139 case GL_INT_SAMPLER_3D: 140 case GL_UNSIGNED_INT_SAMPLER_3D: 141 case GL_SAMPLER_CUBE: 142 case GL_INT_SAMPLER_CUBE: 143 case GL_UNSIGNED_INT_SAMPLER_CUBE: 144 case GL_SAMPLER_1D_SHADOW: 145 case GL_SAMPLER_2D_SHADOW: 146 case GL_SAMPLER_CUBE_SHADOW: 147 case GL_SAMPLER_2D_RECT_ARB: 148 case GL_INT_SAMPLER_2D_RECT: 149 case GL_UNSIGNED_INT_SAMPLER_2D_RECT: 150 case GL_SAMPLER_2D_RECT_SHADOW_ARB: 151 case GL_SAMPLER_1D_ARRAY_EXT: 152 case GL_INT_SAMPLER_1D_ARRAY: 153 case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: 154 case GL_SAMPLER_2D_ARRAY_EXT: 155 case GL_INT_SAMPLER_2D_ARRAY: 156 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 157 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT: 158 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT: 159 case GL_SAMPLER_CUBE_MAP_ARRAY: 160 case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW: 161 case GL_SAMPLER_BUFFER: 162 case GL_INT_SAMPLER_BUFFER: 163 case GL_UNSIGNED_INT_SAMPLER_BUFFER: 164 case GL_SAMPLER_2D_MULTISAMPLE: 165 case GL_INT_SAMPLER_2D_MULTISAMPLE: 166 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: 167 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: 168 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: 169 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: 170 case GL_SAMPLER_EXTERNAL_OES: 171 return GL_TRUE; 172 default: 173 return GL_FALSE; 174 } 175} 176 177/** 178 * Given a uniform index, return the vertex/geometry/fragment program 179 * that has that parameter, plus the position of the parameter in the 180 * parameter/constant buffer. 181 * \param shProg the shader program 182 * \param index the uniform index in [0, NumUniforms-1] 183 * \param progOut returns containing program 184 * \param posOut returns position of the uniform in the param/const buffer 185 * \return GL_TRUE for success, GL_FALSE for invalid index 186 */ 187static GLboolean 188find_uniform_parameter_pos(struct gl_shader_program *shProg, GLint index, 189 struct gl_program **progOut, GLint *posOut) 190{ 191 struct gl_program *prog = NULL; 192 GLint pos; 193 194 if (!shProg->Uniforms || 195 index < 0 || 196 index >= (GLint) shProg->Uniforms->NumUniforms) { 197 return GL_FALSE; 198 } 199 200 pos = shProg->Uniforms->Uniforms[index].VertPos; 201 if (pos >= 0) { 202 prog = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program; 203 } 204 else { 205 pos = shProg->Uniforms->Uniforms[index].FragPos; 206 if (pos >= 0) { 207 prog = shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program; 208 } 209 else { 210 pos = shProg->Uniforms->Uniforms[index].GeomPos; 211 if (pos >= 0) { 212 prog = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program; 213 } 214 } 215 } 216 217 if (!prog || pos < 0) 218 return GL_FALSE; /* should really never happen */ 219 220 *progOut = prog; 221 *posOut = pos; 222 223 return GL_TRUE; 224} 225 226/** 227 * Return pointer to a gl_program_parameter which corresponds to a uniform. 228 * \param shProg the shader program 229 * \param index the uniform index in [0, NumUniforms-1] 230 * \return gl_program_parameter point or NULL if index is invalid 231 */ 232const struct gl_program_parameter * 233get_uniform_parameter(struct gl_shader_program *shProg, GLint index) 234{ 235 struct gl_program *prog; 236 GLint progPos; 237 238 if (find_uniform_parameter_pos(shProg, index, &prog, &progPos)) 239 return &prog->Parameters->Parameters[progPos]; 240 else 241 return NULL; 242} 243 244static unsigned 245get_vector_elements(GLenum type) 246{ 247 switch (type) { 248 case GL_FLOAT: 249 case GL_INT: 250 case GL_BOOL: 251 case GL_UNSIGNED_INT: 252 default: /* Catch all the various sampler types. */ 253 return 1; 254 255 case GL_FLOAT_VEC2: 256 case GL_INT_VEC2: 257 case GL_BOOL_VEC2: 258 case GL_UNSIGNED_INT_VEC2: 259 return 2; 260 261 case GL_FLOAT_VEC3: 262 case GL_INT_VEC3: 263 case GL_BOOL_VEC3: 264 case GL_UNSIGNED_INT_VEC3: 265 return 3; 266 267 case GL_FLOAT_VEC4: 268 case GL_INT_VEC4: 269 case GL_BOOL_VEC4: 270 case GL_UNSIGNED_INT_VEC4: 271 return 4; 272 } 273} 274 275static void 276get_matrix_dims(GLenum type, GLint *rows, GLint *cols) 277{ 278 switch (type) { 279 case GL_FLOAT_MAT2: 280 *rows = *cols = 2; 281 break; 282 case GL_FLOAT_MAT2x3: 283 *rows = 3; 284 *cols = 2; 285 break; 286 case GL_FLOAT_MAT2x4: 287 *rows = 4; 288 *cols = 2; 289 break; 290 case GL_FLOAT_MAT3: 291 *rows = 3; 292 *cols = 3; 293 break; 294 case GL_FLOAT_MAT3x2: 295 *rows = 2; 296 *cols = 3; 297 break; 298 case GL_FLOAT_MAT3x4: 299 *rows = 4; 300 *cols = 3; 301 break; 302 case GL_FLOAT_MAT4: 303 *rows = 4; 304 *cols = 4; 305 break; 306 case GL_FLOAT_MAT4x2: 307 *rows = 2; 308 *cols = 4; 309 break; 310 case GL_FLOAT_MAT4x3: 311 *rows = 3; 312 *cols = 4; 313 break; 314 default: 315 *rows = *cols = 0; 316 } 317} 318 319/** 320 * Determine the number of rows and columns occupied by a uniform 321 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4), 322 * the number of rows = 1 and cols = number of elements in the vector. 323 */ 324static void 325get_uniform_rows_cols(const struct gl_program_parameter *p, 326 GLint *rows, GLint *cols) 327{ 328 get_matrix_dims(p->DataType, rows, cols); 329 if (*rows == 0 && *cols == 0) { 330 /* not a matrix type, probably a float or vector */ 331 *rows = 1; 332 *cols = get_vector_elements(p->DataType); 333 } 334} 335 336static bool 337validate_uniform_parameters(struct gl_context *ctx, 338 struct gl_shader_program *shProg, 339 GLint location, GLsizei count, 340 unsigned *loc, 341 unsigned *array_index, 342 const char *caller, 343 bool negative_one_is_not_valid) 344{ 345 if (!shProg || !shProg->LinkStatus) { 346 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", caller); 347 return false; 348 } 349 350 if (location == -1) { 351 /* For glGetUniform, page 264 (page 278 of the PDF) of the OpenGL 2.1 352 * spec says: 353 * 354 * "The error INVALID_OPERATION is generated if program has not been 355 * linked successfully, or if location is not a valid location for 356 * program." 357 * 358 * For glUniform, page 82 (page 96 of the PDF) of the OpenGL 2.1 spec 359 * says: 360 * 361 * "If the value of location is -1, the Uniform* commands will 362 * silently ignore the data passed in, and the current uniform 363 * values will not be changed." 364 * 365 * Allowing -1 for the location parameter of glUniform allows 366 * applications to avoid error paths in the case that, for example, some 367 * uniform variable is removed by the compiler / linker after 368 * optimization. In this case, the new value of the uniform is dropped 369 * on the floor. For the case of glGetUniform, there is nothing 370 * sensible to do for a location of -1. 371 * 372 * The negative_one_is_not_valid flag selects between the two behaviors. 373 */ 374 if (negative_one_is_not_valid) { 375 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 376 caller, location); 377 } 378 379 return false; 380 } 381 382 /* From page 12 (page 26 of the PDF) of the OpenGL 2.1 spec: 383 * 384 * "If a negative number is provided where an argument of type sizei or 385 * sizeiptr is specified, the error INVALID_VALUE is generated." 386 */ 387 if (count < 0) { 388 _mesa_error(ctx, GL_INVALID_VALUE, "%s(count < 0)", caller); 389 return false; 390 } 391 392 /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: 393 * 394 * "If any of the following conditions occur, an INVALID_OPERATION 395 * error is generated by the Uniform* commands, and no uniform values 396 * are changed: 397 * 398 * ... 399 * 400 * - if no variable with a location of location exists in the 401 * program object currently in use and location is not -1, 402 */ 403 if (location < -1) { 404 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 405 caller, location); 406 return false; 407 } 408 409 _mesa_uniform_split_location_offset(location, loc, array_index); 410 411 if (*loc >= shProg->NumUserUniformStorage) { 412 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 413 caller, location); 414 return false; 415 } 416 417 /* This case should be impossible. The implication is that a call like 418 * glGetUniformLocation(prog, "foo[8]") was successful but "foo" is not an 419 * array. 420 */ 421 if (*array_index != 0 && shProg->UniformStorage[*loc].array_elements == 0) { 422 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 423 caller, location); 424 return false; 425 } 426 return true; 427} 428 429/** 430 * Called via glGetUniform[fiui]v() to get the current value of a uniform. 431 */ 432extern "C" void 433_mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, 434 GLsizei bufSize, enum glsl_base_type returnType, 435 GLvoid *paramsOut) 436{ 437 struct gl_shader_program *shProg = 438 _mesa_lookup_shader_program_err(ctx, program, "glGetUniformfv"); 439 struct gl_uniform_storage *uni; 440 unsigned loc, offset; 441 442 if (!validate_uniform_parameters(ctx, shProg, location, 1, 443 &loc, &offset, "glGetUniform", true)) 444 return; 445 446 uni = &shProg->UniformStorage[loc]; 447 448 { 449 unsigned elements = (uni->type->is_sampler()) 450 ? 1 : uni->type->components(); 451 452 /* Calculate the source base address *BEFORE* modifying elements to 453 * account for the size of the user's buffer. 454 */ 455 const union gl_constant_value *const src = 456 &uni->storage[offset * elements]; 457 458 unsigned bytes = sizeof(uni->storage[0]) * elements; 459 if (bytes > bufSize) { 460 elements = bufSize / sizeof(uni->storage[0]); 461 bytes = bufSize; 462 } 463 464 /* If the return type and the uniform's native type are "compatible," 465 * just memcpy the data. If the types are not compatible, perform a 466 * slower convert-and-copy process. 467 */ 468 if (returnType == uni->type->base_type 469 || ((returnType == GLSL_TYPE_INT 470 || returnType == GLSL_TYPE_UINT 471 || returnType == GLSL_TYPE_SAMPLER) 472 && 473 (uni->type->base_type == GLSL_TYPE_INT 474 || uni->type->base_type == GLSL_TYPE_UINT 475 || uni->type->base_type == GLSL_TYPE_SAMPLER))) { 476 memcpy(paramsOut, src, bytes); 477 } else { 478 union gl_constant_value *const dst = 479 (union gl_constant_value *) paramsOut; 480 481 /* This code could be optimized by putting the loop inside the switch 482 * statements. However, this is not expected to be 483 * performance-critical code. 484 */ 485 for (unsigned i = 0; i < elements; i++) { 486 switch (returnType) { 487 case GLSL_TYPE_FLOAT: 488 switch (uni->type->base_type) { 489 case GLSL_TYPE_UINT: 490 dst[i].f = (float) src[i].u; 491 break; 492 case GLSL_TYPE_INT: 493 case GLSL_TYPE_SAMPLER: 494 dst[i].f = (float) src[i].i; 495 break; 496 case GLSL_TYPE_BOOL: 497 dst[i].f = src[i].i ? 1.0f : 0.0f; 498 break; 499 default: 500 assert(!"Should not get here."); 501 break; 502 } 503 break; 504 505 case GLSL_TYPE_INT: 506 case GLSL_TYPE_UINT: 507 switch (uni->type->base_type) { 508 case GLSL_TYPE_FLOAT: 509 /* While the GL 3.2 core spec doesn't explicitly 510 * state how conversion of float uniforms to integer 511 * values works, in section 6.2 "State Tables" on 512 * page 267 it says: 513 * 514 * "Unless otherwise specified, when floating 515 * point state is returned as integer values or 516 * integer state is returned as floating-point 517 * values it is converted in the fashion 518 * described in section 6.1.2" 519 * 520 * That section, on page 248, says: 521 * 522 * "If GetIntegerv or GetInteger64v are called, 523 * a floating-point value is rounded to the 524 * nearest integer..." 525 */ 526 dst[i].i = IROUND(src[i].f); 527 break; 528 case GLSL_TYPE_BOOL: 529 dst[i].i = src[i].i ? 1 : 0; 530 break; 531 default: 532 assert(!"Should not get here."); 533 break; 534 } 535 break; 536 537 default: 538 assert(!"Should not get here."); 539 break; 540 } 541 } 542 } 543 } 544} 545 546static void 547log_uniform(const void *values, enum glsl_base_type basicType, 548 unsigned rows, unsigned cols, unsigned count, 549 bool transpose, 550 const struct gl_shader_program *shProg, 551 GLint location, 552 const struct gl_uniform_storage *uni) 553{ 554 555 const union gl_constant_value *v = (const union gl_constant_value *) values; 556 const unsigned elems = rows * cols * count; 557 const char *const extra = (cols == 1) ? "uniform" : "uniform matrix"; 558 559 printf("Mesa: set program %u %s \"%s\" (loc %d, type \"%s\", " 560 "transpose = %s) to: ", 561 shProg->Name, extra, uni->name, location, uni->type->name, 562 transpose ? "true" : "false"); 563 for (unsigned i = 0; i < elems; i++) { 564 if (i != 0 && ((i % rows) == 0)) 565 printf(", "); 566 567 switch (basicType) { 568 case GLSL_TYPE_UINT: 569 printf("%u ", v[i].u); 570 break; 571 case GLSL_TYPE_INT: 572 printf("%d ", v[i].i); 573 break; 574 case GLSL_TYPE_FLOAT: 575 printf("%g ", v[i].f); 576 break; 577 default: 578 assert(!"Should not get here."); 579 break; 580 } 581 } 582 printf("\n"); 583 fflush(stdout); 584} 585 586#if 0 587static void 588log_program_parameters(const struct gl_shader_program *shProg) 589{ 590 static const char *stages[] = { 591 "vertex", "fragment", "geometry" 592 }; 593 594 assert(Elements(stages) == MESA_SHADER_TYPES); 595 596 for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 597 if (shProg->_LinkedShaders[i] == NULL) 598 continue; 599 600 const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program; 601 602 printf("Program %d %s shader parameters:\n", 603 shProg->Name, stages[i]); 604 for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) { 605 printf("%s: %p %f %f %f %f\n", 606 prog->Parameters->Parameters[j].Name, 607 prog->Parameters->ParameterValues[j], 608 prog->Parameters->ParameterValues[j][0].f, 609 prog->Parameters->ParameterValues[j][1].f, 610 prog->Parameters->ParameterValues[j][2].f, 611 prog->Parameters->ParameterValues[j][3].f); 612 } 613 } 614 fflush(stdout); 615} 616#endif 617 618/** 619 * Check if the type given by userType is allowed to set a uniform of the 620 * target type. Generally, equivalence is required, but setting Boolean 621 * uniforms can be done with glUniformiv or glUniformfv. 622 */ 623static GLboolean 624compatible_types(GLenum userType, GLenum targetType) 625{ 626 if (userType == targetType) 627 return GL_TRUE; 628 629 if (targetType == GL_BOOL && (userType == GL_FLOAT || 630 userType == GL_UNSIGNED_INT || 631 userType == GL_INT)) 632 return GL_TRUE; 633 634 if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 || 635 userType == GL_UNSIGNED_INT_VEC2 || 636 userType == GL_INT_VEC2)) 637 return GL_TRUE; 638 639 if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 || 640 userType == GL_UNSIGNED_INT_VEC3 || 641 userType == GL_INT_VEC3)) 642 return GL_TRUE; 643 644 if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 || 645 userType == GL_UNSIGNED_INT_VEC4 || 646 userType == GL_INT_VEC4)) 647 return GL_TRUE; 648 649 if (is_sampler_type(targetType) && userType == GL_INT) 650 return GL_TRUE; 651 652 return GL_FALSE; 653} 654 655/** 656 * Set the value of a program's uniform variable. 657 * \param program the program whose uniform to update 658 * \param index the index of the program parameter for the uniform 659 * \param offset additional parameter slot offset (for arrays) 660 * \param type the incoming datatype of 'values' 661 * \param count the number of uniforms to set 662 * \param elems number of elements per uniform (1, 2, 3 or 4) 663 * \param values the new values, of datatype 'type' 664 */ 665static void 666set_program_uniform(struct gl_context *ctx, struct gl_program *program, 667 GLint index, GLint offset, 668 GLenum type, GLsizei count, GLint elems, 669 const void *values) 670{ 671 const struct gl_program_parameter *param = 672 &program->Parameters->Parameters[index]; 673 674 assert(offset >= 0); 675 assert(elems >= 1); 676 assert(elems <= 4); 677 678 if (!compatible_types(type, param->DataType)) { 679 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)"); 680 return; 681 } 682 683 if (index + offset > (GLint) program->Parameters->Size) { 684 /* out of bounds! */ 685 return; 686 } 687 688 if (param->Type == PROGRAM_SAMPLER) { 689 /* This controls which texture unit which is used by a sampler */ 690 GLboolean changed = GL_FALSE; 691 GLint i; 692 693 /* this should have been caught by the compatible_types() check */ 694 ASSERT(type == GL_INT); 695 696 /* loop over number of samplers to change */ 697 for (i = 0; i < count; i++) { 698 GLuint sampler = (GLuint) 699 program->Parameters->ParameterValues[index+offset + i][0].f; 700 GLuint texUnit = ((GLuint *) values)[i]; 701 702 /* check that the sampler (tex unit index) is legal */ 703 if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) { 704 _mesa_error(ctx, GL_INVALID_VALUE, 705 "glUniform1(invalid sampler/tex unit index for '%s')", 706 param->Name); 707 return; 708 } 709 710 /* This maps a sampler to a texture unit: */ 711 if (sampler < MAX_SAMPLERS) { 712#if 0 713 printf("Set program %p sampler %d '%s' to unit %u\n", 714 program, sampler, param->Name, texUnit); 715#endif 716 if (program->SamplerUnits[sampler] != texUnit) { 717 program->SamplerUnits[sampler] = texUnit; 718 changed = GL_TRUE; 719 } 720 } 721 } 722 723 if (changed) { 724 /* When a sampler's value changes it usually requires rewriting 725 * a GPU program's TEX instructions since there may not be a 726 * sampler->texture lookup table. We signal this with the 727 * ProgramStringNotify() callback. 728 */ 729 FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM); 730 _mesa_update_shader_textures_used(program); 731 /* Do we need to care about the return value here? 732 * This should not be the first time the driver was notified of 733 * this program. 734 */ 735 (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program); 736 } 737 } 738 else { 739 /* ordinary uniform variable */ 740 const GLboolean isUniformBool = is_boolean_type(param->DataType); 741 const GLenum basicType = base_uniform_type(type); 742 const GLint slots = (param->Size + 3) / 4; 743 const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType); 744 GLsizei k, i; 745 746 if ((GLint) param->Size > typeSize) { 747 /* an array */ 748 /* we'll ignore extra data below */ 749 } 750 else { 751 /* non-array: count must be at most one; count == 0 is handled 752 * by the loop below 753 */ 754 if (count > 1) { 755 _mesa_error(ctx, GL_INVALID_OPERATION, 756 "glUniform(uniform '%s' is not an array)", 757 param->Name); 758 return; 759 } 760 } 761 762 /* loop over number of array elements */ 763 for (k = 0; k < count; k++) { 764 gl_constant_value *uniformVal; 765 766 if (offset + k >= slots) { 767 /* Extra array data is ignored */ 768 break; 769 } 770 771 /* uniformVal (the destination) is always gl_constant_value[4] */ 772 uniformVal = program->Parameters->ParameterValues[index + offset + k]; 773 774 if (basicType == GL_INT) { 775 const GLint *iValues = ((const GLint *) values) + k * elems; 776 for (i = 0; i < elems; i++) { 777 if (!ctx->Const.NativeIntegers) 778 uniformVal[i].f = (GLfloat) iValues[i]; 779 else 780 uniformVal[i].i = iValues[i]; 781 } 782 } 783 else if (basicType == GL_UNSIGNED_INT) { 784 const GLuint *iValues = ((const GLuint *) values) + k * elems; 785 for (i = 0; i < elems; i++) { 786 if (!ctx->Const.NativeIntegers) 787 uniformVal[i].f = (GLfloat)(GLuint) iValues[i]; 788 else 789 uniformVal[i].u = iValues[i]; 790 } 791 } 792 else { 793 const GLfloat *fValues = ((const GLfloat *) values) + k * elems; 794 assert(basicType == GL_FLOAT); 795 for (i = 0; i < elems; i++) { 796 uniformVal[i].f = fValues[i]; 797 } 798 } 799 800 /* if the uniform is bool-valued, convert to 1 or 0 */ 801 if (isUniformBool) { 802 for (i = 0; i < elems; i++) { 803 if (basicType == GL_FLOAT) 804 uniformVal[i].b = uniformVal[i].f != 0.0f ? 1 : 0; 805 else 806 uniformVal[i].b = uniformVal[i].u ? 1 : 0; 807 808 if (ctx->Const.NativeIntegers) 809 uniformVal[i].u = 810 uniformVal[i].b ? ctx->Const.UniformBooleanTrue : 0; 811 else 812 uniformVal[i].f = uniformVal[i].b ? 1.0f : 0.0f; 813 } 814 } 815 } 816 } 817} 818 819/** 820 * Propagate some values from uniform backing storage to driver storage 821 * 822 * Values propagated from uniform backing storage to driver storage 823 * have all format / type conversions previously requested by the 824 * driver applied. This function is most often called by the 825 * implementations of \c glUniform1f, etc. and \c glUniformMatrix2f, 826 * etc. 827 * 828 * \param uni Uniform whose data is to be propagated to driver storage 829 * \param array_index If \c uni is an array, this is the element of 830 * the array to be propagated. 831 * \param count Number of array elements to propagate. 832 */ 833extern "C" void 834_mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni, 835 unsigned array_index, 836 unsigned count) 837{ 838 unsigned i; 839 840 /* vector_elements and matrix_columns can be 0 for samplers. 841 */ 842 const unsigned components = MAX2(1, uni->type->vector_elements); 843 const unsigned vectors = MAX2(1, uni->type->matrix_columns); 844 845 /* Store the data in the driver's requested type in the driver's storage 846 * areas. 847 */ 848 unsigned src_vector_byte_stride = components * 4; 849 850 for (i = 0; i < uni->num_driver_storage; i++) { 851 struct gl_uniform_driver_storage *const store = &uni->driver_storage[i]; 852 uint8_t *dst = (uint8_t *) store->data; 853 const unsigned extra_stride = 854 store->element_stride - (vectors * store->vector_stride); 855 const uint8_t *src = 856 (uint8_t *) (&uni->storage[array_index * (components * vectors)].i); 857 858#if 0 859 printf("%s: %p[%d] components=%u vectors=%u count=%u vector_stride=%u " 860 "extra_stride=%u\n", 861 __func__, dst, array_index, components, 862 vectors, count, store->vector_stride, extra_stride); 863#endif 864 865 dst += array_index * store->element_stride; 866 867 switch (store->format) { 868 case uniform_native: 869 case uniform_bool_int_0_1: { 870 unsigned j; 871 unsigned v; 872 873 for (j = 0; j < count; j++) { 874 for (v = 0; v < vectors; v++) { 875 memcpy(dst, src, src_vector_byte_stride); 876 src += src_vector_byte_stride; 877 dst += store->vector_stride; 878 } 879 880 dst += extra_stride; 881 } 882 break; 883 } 884 885 case uniform_int_float: 886 case uniform_bool_float: { 887 const int *isrc = (const int *) src; 888 unsigned j; 889 unsigned v; 890 unsigned c; 891 892 for (j = 0; j < count; j++) { 893 for (v = 0; v < vectors; v++) { 894 for (c = 0; c < components; c++) { 895 ((float *) dst)[c] = (float) *isrc; 896 isrc++; 897 } 898 899 dst += store->vector_stride; 900 } 901 902 dst += extra_stride; 903 } 904 break; 905 } 906 907 case uniform_bool_int_0_not0: { 908 const int *isrc = (const int *) src; 909 unsigned j; 910 unsigned v; 911 unsigned c; 912 913 for (j = 0; j < count; j++) { 914 for (v = 0; v < vectors; v++) { 915 for (c = 0; c < components; c++) { 916 ((int *) dst)[c] = *isrc == 0 ? 0 : ~0; 917 isrc++; 918 } 919 920 dst += store->vector_stride; 921 } 922 923 dst += extra_stride; 924 } 925 break; 926 } 927 928 default: 929 assert(!"Should not get here."); 930 break; 931 } 932 } 933} 934 935/** 936 * Called via glUniform*() functions. 937 */ 938extern "C" void 939_mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, 940 GLint location, GLsizei count, 941 const GLvoid *values, GLenum type) 942{ 943 unsigned loc, offset; 944 unsigned components; 945 unsigned src_components; 946 unsigned i; 947 enum glsl_base_type basicType; 948 struct gl_uniform_storage *uni; 949 950 ASSERT_OUTSIDE_BEGIN_END(ctx); 951 952 if (!validate_uniform_parameters(ctx, shProg, location, count, 953 &loc, &offset, "glUniform", false)) 954 return; 955 956 uni = &shProg->UniformStorage[loc]; 957 958 /* Verify that the types are compatible. 959 */ 960 switch (type) { 961 case GL_FLOAT: 962 basicType = GLSL_TYPE_FLOAT; 963 src_components = 1; 964 break; 965 case GL_FLOAT_VEC2: 966 basicType = GLSL_TYPE_FLOAT; 967 src_components = 2; 968 break; 969 case GL_FLOAT_VEC3: 970 basicType = GLSL_TYPE_FLOAT; 971 src_components = 3; 972 break; 973 case GL_FLOAT_VEC4: 974 basicType = GLSL_TYPE_FLOAT; 975 src_components = 4; 976 break; 977 case GL_UNSIGNED_INT: 978 basicType = GLSL_TYPE_UINT; 979 src_components = 1; 980 break; 981 case GL_UNSIGNED_INT_VEC2: 982 basicType = GLSL_TYPE_UINT; 983 src_components = 2; 984 break; 985 case GL_UNSIGNED_INT_VEC3: 986 basicType = GLSL_TYPE_UINT; 987 src_components = 3; 988 break; 989 case GL_UNSIGNED_INT_VEC4: 990 basicType = GLSL_TYPE_UINT; 991 src_components = 4; 992 break; 993 case GL_INT: 994 basicType = GLSL_TYPE_INT; 995 src_components = 1; 996 break; 997 case GL_INT_VEC2: 998 basicType = GLSL_TYPE_INT; 999 src_components = 2; 1000 break; 1001 case GL_INT_VEC3: 1002 basicType = GLSL_TYPE_INT; 1003 src_components = 3; 1004 break; 1005 case GL_INT_VEC4: 1006 basicType = GLSL_TYPE_INT; 1007 src_components = 4; 1008 break; 1009 case GL_BOOL: 1010 case GL_BOOL_VEC2: 1011 case GL_BOOL_VEC3: 1012 case GL_BOOL_VEC4: 1013 case GL_FLOAT_MAT2: 1014 case GL_FLOAT_MAT2x3: 1015 case GL_FLOAT_MAT2x4: 1016 case GL_FLOAT_MAT3x2: 1017 case GL_FLOAT_MAT3: 1018 case GL_FLOAT_MAT3x4: 1019 case GL_FLOAT_MAT4x2: 1020 case GL_FLOAT_MAT4x3: 1021 case GL_FLOAT_MAT4: 1022 default: 1023 _mesa_problem(NULL, "Invalid type in %s", __func__); 1024 return; 1025 } 1026 1027 if (uni->type->is_sampler()) { 1028 components = 1; 1029 } else { 1030 components = uni->type->vector_elements; 1031 } 1032 1033 bool match; 1034 switch (uni->type->base_type) { 1035 case GLSL_TYPE_BOOL: 1036 match = true; 1037 break; 1038 case GLSL_TYPE_SAMPLER: 1039 match = (basicType == GLSL_TYPE_INT); 1040 break; 1041 default: 1042 match = (basicType == uni->type->base_type); 1043 break; 1044 } 1045 1046 if (uni->type->is_matrix() || components != src_components || !match) { 1047 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)"); 1048 return; 1049 } 1050 1051 if (ctx->Shader.Flags & GLSL_UNIFORMS) { 1052 log_uniform(values, basicType, components, 1, count, 1053 false, shProg, location, uni); 1054 } 1055 1056 /* Page 100 (page 116 of the PDF) of the OpenGL 3.0 spec says: 1057 * 1058 * "Setting a sampler's value to i selects texture image unit number 1059 * i. The values of i range from zero to the implementation- dependent 1060 * maximum supported number of texture image units." 1061 * 1062 * In addition, table 2.3, "Summary of GL errors," on page 17 (page 33 of 1063 * the PDF) says: 1064 * 1065 * "Error Description Offending command 1066 * ignored? 1067 * ... 1068 * INVALID_VALUE Numeric argument out of range Yes" 1069 * 1070 * Based on that, when an invalid sampler is specified, we generate a 1071 * GL_INVALID_VALUE error and ignore the command. 1072 */ 1073 if (uni->type->is_sampler()) { 1074 for (i = 0; i < count; i++) { 1075 const unsigned texUnit = ((unsigned *) values)[i]; 1076 1077 /* check that the sampler (tex unit index) is legal */ 1078 if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) { 1079 _mesa_error(ctx, GL_INVALID_VALUE, 1080 "glUniform1i(invalid sampler/tex unit index for " 1081 "uniform %d)", 1082 location); 1083 return; 1084 } 1085 } 1086 } 1087 1088 /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: 1089 * 1090 * "When loading N elements starting at an arbitrary position k in a 1091 * uniform declared as an array, elements k through k + N - 1 in the 1092 * array will be replaced with the new values. Values for any array 1093 * element that exceeds the highest array element index used, as 1094 * reported by GetActiveUniform, will be ignored by the GL." 1095 * 1096 * Clamp 'count' to a valid value. Note that for non-arrays a count > 1 1097 * will have already generated an error. 1098 */ 1099 if (uni->array_elements != 0) { 1100 if (offset >= uni->array_elements) 1101 return; 1102 1103 count = MIN2(count, (uni->array_elements - offset)); 1104 } 1105 1106 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); 1107 1108 /* Store the data in the "actual type" backing storage for the uniform. 1109 */ 1110 if (!uni->type->is_boolean()) { 1111 memcpy(&uni->storage[components * offset], values, 1112 sizeof(uni->storage[0]) * components * count); 1113 } else { 1114 const union gl_constant_value *src = 1115 (const union gl_constant_value *) values; 1116 union gl_constant_value *dst = &uni->storage[components * offset]; 1117 const unsigned elems = components * count; 1118 1119 for (i = 0; i < elems; i++) { 1120 if (basicType == GLSL_TYPE_FLOAT) { 1121 dst[i].i = src[i].f != 0.0f ? 1 : 0; 1122 } else { 1123 dst[i].i = src[i].i != 0 ? 1 : 0; 1124 } 1125 } 1126 } 1127 1128 uni->initialized = true; 1129 1130 _mesa_propagate_uniforms_to_driver_storage(uni, offset, count); 1131 1132 /* If the uniform is a sampler, do the extra magic necessary to propagate 1133 * the changes through. 1134 */ 1135 if (uni->type->is_sampler()) { 1136 for (i = 0; i < count; i++) { 1137 shProg->SamplerUnits[uni->sampler + offset + i] = 1138 ((unsigned *) values)[i]; 1139 } 1140 1141 bool flushed = false; 1142 for (i = 0; i < MESA_SHADER_TYPES; i++) { 1143 struct gl_program *prog; 1144 1145 if (shProg->_LinkedShaders[i] == NULL) 1146 continue; 1147 1148 prog = shProg->_LinkedShaders[i]->Program; 1149 1150 assert(sizeof(prog->SamplerUnits) == sizeof(shProg->SamplerUnits)); 1151 1152 if (memcmp(prog->SamplerUnits, 1153 shProg->SamplerUnits, 1154 sizeof(shProg->SamplerUnits)) != 0) { 1155 if (!flushed) { 1156 FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM); 1157 flushed = true; 1158 } 1159 1160 memcpy(prog->SamplerUnits, 1161 shProg->SamplerUnits, 1162 sizeof(shProg->SamplerUnits)); 1163 1164 _mesa_update_shader_textures_used(prog); 1165 (void) ctx->Driver.ProgramStringNotify(ctx, prog->Target, prog); 1166 } 1167 } 1168 } 1169} 1170 1171/** 1172 * Set a matrix-valued program parameter. 1173 */ 1174static void 1175set_program_uniform_matrix(struct gl_context *ctx, struct gl_program *program, 1176 GLuint index, GLuint offset, 1177 GLuint count, GLuint rows, GLuint cols, 1178 GLboolean transpose, const GLfloat *values) 1179{ 1180 GLuint mat, row, col; 1181 GLuint src = 0; 1182 const struct gl_program_parameter *param = 1183 &program->Parameters->Parameters[index]; 1184 const GLuint slots = (param->Size + 3) / 4; 1185 const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType); 1186 GLint nr, nc; 1187 1188 /* check that the number of rows, columns is correct */ 1189 get_matrix_dims(param->DataType, &nr, &nc); 1190 if (rows != nr || cols != nc) { 1191 _mesa_error(ctx, GL_INVALID_OPERATION, 1192 "glUniformMatrix(matrix size mismatch)"); 1193 return; 1194 } 1195 1196 if ((GLint) param->Size <= typeSize) { 1197 /* non-array: count must be at most one; count == 0 is handled 1198 * by the loop below 1199 */ 1200 if (count > 1) { 1201 _mesa_error(ctx, GL_INVALID_OPERATION, 1202 "glUniformMatrix(uniform is not an array)"); 1203 return; 1204 } 1205 } 1206 1207 /* 1208 * Note: the _columns_ of a matrix are stored in program registers, not 1209 * the rows. So, the loops below look a little funny. 1210 * XXX could optimize this a bit... 1211 */ 1212 1213 /* loop over matrices */ 1214 for (mat = 0; mat < count; mat++) { 1215 1216 /* each matrix: */ 1217 for (col = 0; col < cols; col++) { 1218 GLfloat *v; 1219 if (offset >= slots) { 1220 /* Ignore writes beyond the end of (the used part of) an array */ 1221 return; 1222 } 1223 v = (GLfloat *) program->Parameters->ParameterValues[index + offset]; 1224 for (row = 0; row < rows; row++) { 1225 if (transpose) { 1226 v[row] = values[src + row * cols + col]; 1227 } 1228 else { 1229 v[row] = values[src + col * rows + row]; 1230 } 1231 } 1232 1233 offset++; 1234 } 1235 1236 src += rows * cols; /* next matrix */ 1237 } 1238} 1239 1240/** 1241 * Called by glUniformMatrix*() functions. 1242 * Note: cols=2, rows=4 ==> array[2] of vec4 1243 */ 1244extern "C" void 1245_mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, 1246 GLint cols, GLint rows, 1247 GLint location, GLsizei count, 1248 GLboolean transpose, const GLfloat *values) 1249{ 1250 unsigned loc, offset; 1251 unsigned vectors; 1252 unsigned components; 1253 unsigned elements; 1254 struct gl_uniform_storage *uni; 1255 1256 ASSERT_OUTSIDE_BEGIN_END(ctx); 1257 1258 if (!validate_uniform_parameters(ctx, shProg, location, count, 1259 &loc, &offset, "glUniformMatrix", false)) 1260 return; 1261 1262 uni = &shProg->UniformStorage[loc]; 1263 if (!uni->type->is_matrix()) { 1264 _mesa_error(ctx, GL_INVALID_OPERATION, 1265 "glUniformMatrix(non-matrix uniform)"); 1266 return; 1267 } 1268 1269 assert(!uni->type->is_sampler()); 1270 vectors = uni->type->matrix_columns; 1271 components = uni->type->vector_elements; 1272 1273 /* Verify that the types are compatible. This is greatly simplified for 1274 * matrices because they can only have a float base type. 1275 */ 1276 if (vectors != cols || components != rows) { 1277 _mesa_error(ctx, GL_INVALID_OPERATION, 1278 "glUniformMatrix(matrix size mismatch)"); 1279 return; 1280 } 1281 1282 if (ctx->Shader.Flags & GLSL_UNIFORMS) { 1283 log_uniform(values, GLSL_TYPE_FLOAT, components, vectors, count, 1284 bool(transpose), shProg, location, uni); 1285 } 1286 1287 /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: 1288 * 1289 * "When loading N elements starting at an arbitrary position k in a 1290 * uniform declared as an array, elements k through k + N - 1 in the 1291 * array will be replaced with the new values. Values for any array 1292 * element that exceeds the highest array element index used, as 1293 * reported by GetActiveUniform, will be ignored by the GL." 1294 * 1295 * Clamp 'count' to a valid value. Note that for non-arrays a count > 1 1296 * will have already generated an error. 1297 */ 1298 if (uni->array_elements != 0) { 1299 if (offset >= uni->array_elements) 1300 return; 1301 1302 count = MIN2(count, (uni->array_elements - offset)); 1303 } 1304 1305 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); 1306 1307 /* Store the data in the "actual type" backing storage for the uniform. 1308 */ 1309 elements = components * vectors; 1310 1311 if (!transpose) { 1312 memcpy(&uni->storage[elements * offset], values, 1313 sizeof(uni->storage[0]) * elements * count); 1314 } else { 1315 /* Copy and transpose the matrix. 1316 */ 1317 const float *src = values; 1318 float *dst = &uni->storage[elements * offset].f; 1319 1320 for (unsigned i = 0; i < count; i++) { 1321 for (unsigned r = 0; r < rows; r++) { 1322 for (unsigned c = 0; c < cols; c++) { 1323 dst[(c * components) + r] = src[c + (r * vectors)]; 1324 } 1325 } 1326 1327 dst += elements; 1328 src += elements; 1329 } 1330 } 1331 1332 uni->initialized = true; 1333 1334 _mesa_propagate_uniforms_to_driver_storage(uni, offset, count); 1335} 1336 1337/** 1338 * Called via glGetUniformLocation(). 1339 * 1340 * The return value will encode two values, the uniform location and an 1341 * offset (used for arrays, structs). 1342 */ 1343extern "C" GLint 1344_mesa_get_uniform_location(struct gl_context *ctx, 1345 struct gl_shader_program *shProg, 1346 const GLchar *name) 1347{ 1348 const size_t len = strlen(name); 1349 long offset; 1350 bool array_lookup; 1351 char *name_copy; 1352 1353 /* If the name ends with a ']', assume that it refers to some element of an 1354 * array. Malformed array references will fail the hash table look up 1355 * below, so it doesn't matter that they are not caught here. This code 1356 * only wants to catch the "leaf" array references so that arrays of 1357 * structures containing arrays will be handled correctly. 1358 */ 1359 if (name[len-1] == ']') { 1360 unsigned i; 1361 1362 /* Walk backwards over the string looking for a non-digit character. 1363 * This had better be the opening bracket for an array index. 1364 * 1365 * Initially, i specifies the location of the ']'. Since the string may 1366 * contain only the ']' charcater, walk backwards very carefully. 1367 */ 1368 for (i = len - 1; (i > 0) && isdigit(name[i-1]); --i) 1369 /* empty */ ; 1370 1371 /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says: 1372 * 1373 * "The first element of a uniform array is identified using the 1374 * name of the uniform array appended with "[0]". Except if the last 1375 * part of the string name indicates a uniform array, then the 1376 * location of the first element of that array can be retrieved by 1377 * either using the name of the uniform array, or the name of the 1378 * uniform array appended with "[0]"." 1379 * 1380 * Page 79 (page 93 of the PDF) of the OpenGL 2.1 spec says: 1381 * 1382 * "name must be a null terminated string, without white space." 1383 * 1384 * Return an error if there is no opening '[' to match the closing ']'. 1385 * An error will also be returned if there is intervening white space 1386 * (or other non-digit characters) before the opening '['. 1387 */ 1388 if ((i == 0) || name[i-1] != '[') 1389 return -1; 1390 1391 /* Return an error if there are no digits between the opening '[' to 1392 * match the closing ']'. 1393 */ 1394 if (i == (len - 1)) 1395 return -1; 1396 1397 /* Make a new string that is a copy of the old string up to (but not 1398 * including) the '[' character. 1399 */ 1400 name_copy = (char *) malloc(i); 1401 memcpy(name_copy, name, i - 1); 1402 name_copy[i-1] = '\0'; 1403 1404 offset = strtol(&name[i], NULL, 10); 1405 if (offset < 0) 1406 return -1; 1407 1408 array_lookup = true; 1409 } else { 1410 name_copy = (char *) name; 1411 offset = 0; 1412 array_lookup = false; 1413 } 1414 1415 unsigned location; 1416 const bool found = shProg->UniformHash->get(location, name_copy); 1417 1418 assert(!found 1419 || strcmp(name_copy, shProg->UniformStorage[location].name) == 0); 1420 1421 /* Free the temporary buffer *before* possibly returning an error. 1422 */ 1423 if (name_copy != name) 1424 free(name_copy); 1425 1426 if (!found) 1427 return -1; 1428 1429 /* Since array_elements is 0 for non-arrays, this causes look-ups of 'a[0]' 1430 * to (correctly) fail if 'a' is not an array. 1431 */ 1432 if (array_lookup && shProg->UniformStorage[location].array_elements == 0) { 1433 return -1; 1434 } 1435 1436 return _mesa_uniform_merge_location_offset(location, offset); 1437} 1438