1 /* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved. 5 * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved. 6 * Copyright 2010, 2011 Intel Corporation 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 * OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27 #include <stdlib.h> 28 29 #include "main/core.h" 30 #include "main/context.h" 31 #include "main/shaderapi.h" 32 #include "main/shaderobj.h" 33 #include "main/uniforms.h" 34 #include "compiler/glsl/ir.h" 35 #include "compiler/glsl/ir_uniform.h" 36 #include "compiler/glsl/glsl_parser_extras.h" 37 #include "compiler/glsl/program.h" 38 #include "util/bitscan.h" 39 40 41 extern "C" void GLAPIENTRY 42 _mesa_GetActiveUniform(GLuint program, GLuint index, 43 GLsizei maxLength, GLsizei *length, GLint *size, 44 GLenum *type, GLcharARB *nameOut) 45 { 46 GET_CURRENT_CONTEXT(ctx); 47 struct gl_shader_program *shProg; 48 struct gl_program_resource *res; 49 50 if (maxLength < 0) { 51 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(maxLength < 0)"); 52 return; 53 } 54 55 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); 56 if (!shProg) 57 return; 58 59 res = _mesa_program_resource_find_index((struct gl_shader_program *) shProg, 60 GL_UNIFORM, index); 61 62 if (!res) { 63 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); 64 return; 65 } 66 67 if (nameOut) 68 _mesa_get_program_resource_name(shProg, GL_UNIFORM, index, maxLength, 69 length, nameOut, "glGetActiveUniform"); 70 if (type) 71 _mesa_program_resource_prop((struct gl_shader_program *) shProg, 72 res, index, GL_TYPE, (GLint*) type, 73 "glGetActiveUniform"); 74 if (size) 75 _mesa_program_resource_prop((struct gl_shader_program *) shProg, 76 res, index, GL_ARRAY_SIZE, (GLint*) size, 77 "glGetActiveUniform"); 78 } 79 80 static GLenum 81 resource_prop_from_uniform_prop(GLenum uni_prop) 82 { 83 switch (uni_prop) { 84 case GL_UNIFORM_TYPE: 85 return GL_TYPE; 86 case GL_UNIFORM_SIZE: 87 return GL_ARRAY_SIZE; 88 case GL_UNIFORM_NAME_LENGTH: 89 return GL_NAME_LENGTH; 90 case GL_UNIFORM_BLOCK_INDEX: 91 return GL_BLOCK_INDEX; 92 case GL_UNIFORM_OFFSET: 93 return GL_OFFSET; 94 case GL_UNIFORM_ARRAY_STRIDE: 95 return GL_ARRAY_STRIDE; 96 case GL_UNIFORM_MATRIX_STRIDE: 97 return GL_MATRIX_STRIDE; 98 case GL_UNIFORM_IS_ROW_MAJOR: 99 return GL_IS_ROW_MAJOR; 100 case GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX: 101 return GL_ATOMIC_COUNTER_BUFFER_INDEX; 102 default: 103 return 0; 104 } 105 } 106 107 extern "C" void GLAPIENTRY 108 _mesa_GetActiveUniformsiv(GLuint program, 109 GLsizei uniformCount, 110 const GLuint *uniformIndices, 111 GLenum pname, 112 GLint *params) 113 { 114 GET_CURRENT_CONTEXT(ctx); 115 struct gl_shader_program *shProg; 116 struct gl_program_resource *res; 117 GLenum res_prop; 118 119 if (uniformCount < 0) { 120 _mesa_error(ctx, GL_INVALID_VALUE, 121 "glGetActiveUniformsiv(uniformCount < 0)"); 122 return; 123 } 124 125 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); 126 if (!shProg) 127 return; 128 129 res_prop = resource_prop_from_uniform_prop(pname); 130 131 /* We need to first verify that each entry exists as active uniform. If 132 * not, generate error and do not cause any other side effects. 133 * 134 * In the case of and error condition, Page 16 (section 2.3.1 Errors) 135 * of the OpenGL 4.5 spec says: 136 * 137 * "If the generating command modifies values through a pointer argu- 138 * ment, no change is made to these values." 139 */ 140 for (int i = 0; i < uniformCount; i++) { 141 if (!_mesa_program_resource_find_index(shProg, GL_UNIFORM, 142 uniformIndices[i])) { 143 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)"); 144 return; 145 } 146 } 147 148 for (int i = 0; i < uniformCount; i++) { 149 res = _mesa_program_resource_find_index(shProg, GL_UNIFORM, 150 uniformIndices[i]); 151 if (!_mesa_program_resource_prop(shProg, res, uniformIndices[i], 152 res_prop, ¶ms[i], 153 "glGetActiveUniformsiv")) 154 break; 155 } 156 } 157 158 static struct gl_uniform_storage * 159 validate_uniform_parameters(struct gl_context *ctx, 160 struct gl_shader_program *shProg, 161 GLint location, GLsizei count, 162 unsigned *array_index, 163 const char *caller) 164 { 165 if (shProg == NULL) { 166 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", caller); 167 return NULL; 168 } 169 170 /* From page 12 (page 26 of the PDF) of the OpenGL 2.1 spec: 171 * 172 * "If a negative number is provided where an argument of type sizei or 173 * sizeiptr is specified, the error INVALID_VALUE is generated." 174 */ 175 if (count < 0) { 176 _mesa_error(ctx, GL_INVALID_VALUE, "%s(count < 0)", caller); 177 return NULL; 178 } 179 180 /* Check that the given location is in bounds of uniform remap table. 181 * Unlinked programs will have NumUniformRemapTable == 0, so we can take 182 * the shProg->data->LinkStatus check out of the main path. 183 */ 184 if (unlikely(location >= (GLint) shProg->NumUniformRemapTable)) { 185 if (!shProg->data->LinkStatus) 186 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", 187 caller); 188 else 189 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 190 caller, location); 191 192 return NULL; 193 } 194 195 if (location == -1) { 196 if (!shProg->data->LinkStatus) 197 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", 198 caller); 199 200 return NULL; 201 } 202 203 /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: 204 * 205 * "If any of the following conditions occur, an INVALID_OPERATION 206 * error is generated by the Uniform* commands, and no uniform values 207 * are changed: 208 * 209 * ... 210 * 211 * - if no variable with a location of location exists in the 212 * program object currently in use and location is not -1, 213 * - if count is greater than one, and the uniform declared in the 214 * shader is not an array variable, 215 */ 216 if (location < -1 || !shProg->UniformRemapTable[location]) { 217 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 218 caller, location); 219 return NULL; 220 } 221 222 /* If the driver storage pointer in remap table is -1, we ignore silently. 223 * 224 * GL_ARB_explicit_uniform_location spec says: 225 * "What happens if Uniform* is called with an explicitly defined 226 * uniform location, but that uniform is deemed inactive by the 227 * linker? 228 * 229 * RESOLVED: The call is ignored for inactive uniform variables and 230 * no error is generated." 231 * 232 */ 233 if (shProg->UniformRemapTable[location] == 234 INACTIVE_UNIFORM_EXPLICIT_LOCATION) 235 return NULL; 236 237 struct gl_uniform_storage *const uni = shProg->UniformRemapTable[location]; 238 239 /* Even though no location is assigned to a built-in uniform and this 240 * function should already have returned NULL, this test makes it explicit 241 * that we are not allowing to update the value of a built-in. 242 */ 243 if (uni->builtin) 244 return NULL; 245 246 if (uni->array_elements == 0) { 247 if (count > 1) { 248 _mesa_error(ctx, GL_INVALID_OPERATION, 249 "%s(count = %u for non-array \"%s\"@%d)", 250 caller, count, uni->name, location); 251 return NULL; 252 } 253 254 assert((location - uni->remap_location) == 0); 255 *array_index = 0; 256 } else { 257 /* The array index specified by the uniform location is just the uniform 258 * location minus the base location of of the uniform. 259 */ 260 *array_index = location - uni->remap_location; 261 262 /* If the uniform is an array, check that array_index is in bounds. 263 * array_index is unsigned so no need to check for less than zero. 264 */ 265 if (*array_index >= uni->array_elements) { 266 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 267 caller, location); 268 return NULL; 269 } 270 } 271 return uni; 272 } 273 274 /** 275 * Called via glGetUniform[fiui]v() to get the current value of a uniform. 276 */ 277 extern "C" void 278 _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, 279 GLsizei bufSize, enum glsl_base_type returnType, 280 GLvoid *paramsOut) 281 { 282 struct gl_shader_program *shProg = 283 _mesa_lookup_shader_program_err(ctx, program, "glGetUniformfv"); 284 unsigned offset; 285 286 struct gl_uniform_storage *const uni = 287 validate_uniform_parameters(ctx, shProg, location, 1, 288 &offset, "glGetUniform"); 289 if (uni == NULL) { 290 /* For glGetUniform, page 264 (page 278 of the PDF) of the OpenGL 2.1 291 * spec says: 292 * 293 * "The error INVALID_OPERATION is generated if program has not been 294 * linked successfully, or if location is not a valid location for 295 * program." 296 * 297 * For glUniform, page 82 (page 96 of the PDF) of the OpenGL 2.1 spec 298 * says: 299 * 300 * "If the value of location is -1, the Uniform* commands will 301 * silently ignore the data passed in, and the current uniform 302 * values will not be changed." 303 * 304 * Allowing -1 for the location parameter of glUniform allows 305 * applications to avoid error paths in the case that, for example, some 306 * uniform variable is removed by the compiler / linker after 307 * optimization. In this case, the new value of the uniform is dropped 308 * on the floor. For the case of glGetUniform, there is nothing 309 * sensible to do for a location of -1. 310 * 311 * If the location was -1, validate_unfirom_parameters will return NULL 312 * without raising an error. Raise the error here. 313 */ 314 if (location == -1) { 315 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniform(location=%d)", 316 location); 317 } 318 319 return; 320 } 321 322 { 323 unsigned elements = (uni->type->is_sampler()) 324 ? 1 : uni->type->components(); 325 const int dmul = uni->type->is_64bit() ? 2 : 1; 326 const int rmul = glsl_base_type_is_64bit(returnType) ? 2 : 1; 327 328 /* Calculate the source base address *BEFORE* modifying elements to 329 * account for the size of the user's buffer. 330 */ 331 const union gl_constant_value *const src = 332 &uni->storage[offset * elements * dmul]; 333 334 assert(returnType == GLSL_TYPE_FLOAT || returnType == GLSL_TYPE_INT || 335 returnType == GLSL_TYPE_UINT || returnType == GLSL_TYPE_DOUBLE); 336 337 /* doubles have a different size than the other 3 types */ 338 unsigned bytes = sizeof(src[0]) * elements * rmul; 339 if (bufSize < 0 || bytes > (unsigned) bufSize) { 340 _mesa_error( ctx, GL_INVALID_OPERATION, 341 "glGetnUniform*vARB(out of bounds: bufSize is %d," 342 " but %u bytes are required)", bufSize, bytes ); 343 return; 344 } 345 346 /* If the return type and the uniform's native type are "compatible," 347 * just memcpy the data. If the types are not compatible, perform a 348 * slower convert-and-copy process. 349 */ 350 if (returnType == uni->type->base_type 351 || ((returnType == GLSL_TYPE_INT 352 || returnType == GLSL_TYPE_UINT) 353 && 354 (uni->type->base_type == GLSL_TYPE_INT 355 || uni->type->base_type == GLSL_TYPE_UINT 356 || uni->type->base_type == GLSL_TYPE_SAMPLER 357 || uni->type->base_type == GLSL_TYPE_IMAGE))) { 358 memcpy(paramsOut, src, bytes); 359 } else { 360 union gl_constant_value *const dst = 361 (union gl_constant_value *) paramsOut; 362 /* This code could be optimized by putting the loop inside the switch 363 * statements. However, this is not expected to be 364 * performance-critical code. 365 */ 366 for (unsigned i = 0; i < elements; i++) { 367 int sidx = i * dmul; 368 int didx = i * rmul; 369 370 switch (returnType) { 371 case GLSL_TYPE_FLOAT: 372 switch (uni->type->base_type) { 373 case GLSL_TYPE_UINT: 374 dst[didx].f = (float) src[sidx].u; 375 break; 376 case GLSL_TYPE_INT: 377 case GLSL_TYPE_SAMPLER: 378 case GLSL_TYPE_IMAGE: 379 dst[didx].f = (float) src[sidx].i; 380 break; 381 case GLSL_TYPE_BOOL: 382 dst[didx].f = src[sidx].i ? 1.0f : 0.0f; 383 break; 384 case GLSL_TYPE_DOUBLE: { 385 double tmp; 386 memcpy(&tmp, &src[sidx].f, sizeof(tmp)); 387 dst[didx].f = tmp; 388 break; 389 } 390 default: 391 assert(!"Should not get here."); 392 break; 393 } 394 break; 395 case GLSL_TYPE_DOUBLE: 396 switch (uni->type->base_type) { 397 case GLSL_TYPE_UINT: { 398 double tmp = src[sidx].u; 399 memcpy(&dst[didx].f, &tmp, sizeof(tmp)); 400 break; 401 } 402 case GLSL_TYPE_INT: 403 case GLSL_TYPE_SAMPLER: 404 case GLSL_TYPE_IMAGE: { 405 double tmp = src[sidx].i; 406 memcpy(&dst[didx].f, &tmp, sizeof(tmp)); 407 break; 408 } 409 case GLSL_TYPE_BOOL: { 410 double tmp = src[sidx].i ? 1.0 : 0.0; 411 memcpy(&dst[didx].f, &tmp, sizeof(tmp)); 412 break; 413 } 414 case GLSL_TYPE_FLOAT: { 415 double tmp = src[sidx].f; 416 memcpy(&dst[didx].f, &tmp, sizeof(tmp)); 417 break; 418 } 419 default: 420 assert(!"Should not get here."); 421 break; 422 } 423 break; 424 case GLSL_TYPE_INT: 425 case GLSL_TYPE_UINT: 426 switch (uni->type->base_type) { 427 case GLSL_TYPE_FLOAT: 428 /* While the GL 3.2 core spec doesn't explicitly 429 * state how conversion of float uniforms to integer 430 * values works, in section 6.2 "State Tables" on 431 * page 267 it says: 432 * 433 * "Unless otherwise specified, when floating 434 * point state is returned as integer values or 435 * integer state is returned as floating-point 436 * values it is converted in the fashion 437 * described in section 6.1.2" 438 * 439 * That section, on page 248, says: 440 * 441 * "If GetIntegerv or GetInteger64v are called, 442 * a floating-point value is rounded to the 443 * nearest integer..." 444 */ 445 dst[didx].i = IROUND(src[sidx].f); 446 break; 447 case GLSL_TYPE_BOOL: 448 dst[didx].i = src[sidx].i ? 1 : 0; 449 break; 450 case GLSL_TYPE_DOUBLE: { 451 double tmp; 452 memcpy(&tmp, &src[sidx].f, sizeof(tmp)); 453 dst[didx].i = IROUNDD(tmp); 454 break; 455 } 456 default: 457 assert(!"Should not get here."); 458 break; 459 } 460 break; 461 462 default: 463 assert(!"Should not get here."); 464 break; 465 } 466 } 467 } 468 } 469 } 470 471 static void 472 log_uniform(const void *values, enum glsl_base_type basicType, 473 unsigned rows, unsigned cols, unsigned count, 474 bool transpose, 475 const struct gl_shader_program *shProg, 476 GLint location, 477 const struct gl_uniform_storage *uni) 478 { 479 480 const union gl_constant_value *v = (const union gl_constant_value *) values; 481 const unsigned elems = rows * cols * count; 482 const char *const extra = (cols == 1) ? "uniform" : "uniform matrix"; 483 484 printf("Mesa: set program %u %s \"%s\" (loc %d, type \"%s\", " 485 "transpose = %s) to: ", 486 shProg->Name, extra, uni->name, location, uni->type->name, 487 transpose ? "true" : "false"); 488 for (unsigned i = 0; i < elems; i++) { 489 if (i != 0 && ((i % rows) == 0)) 490 printf(", "); 491 492 switch (basicType) { 493 case GLSL_TYPE_UINT: 494 printf("%u ", v[i].u); 495 break; 496 case GLSL_TYPE_INT: 497 printf("%d ", v[i].i); 498 break; 499 case GLSL_TYPE_FLOAT: 500 printf("%g ", v[i].f); 501 break; 502 case GLSL_TYPE_DOUBLE: { 503 double tmp; 504 memcpy(&tmp, &v[i * 2].f, sizeof(tmp)); 505 printf("%g ", tmp); 506 break; 507 } 508 default: 509 assert(!"Should not get here."); 510 break; 511 } 512 } 513 printf("\n"); 514 fflush(stdout); 515 } 516 517 #if 0 518 static void 519 log_program_parameters(const struct gl_shader_program *shProg) 520 { 521 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 522 if (shProg->_LinkedShaders[i] == NULL) 523 continue; 524 525 const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program; 526 527 printf("Program %d %s shader parameters:\n", 528 shProg->Name, _mesa_shader_stage_to_string(i)); 529 for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) { 530 printf("%s: %p %f %f %f %f\n", 531 prog->Parameters->Parameters[j].Name, 532 prog->Parameters->ParameterValues[j], 533 prog->Parameters->ParameterValues[j][0].f, 534 prog->Parameters->ParameterValues[j][1].f, 535 prog->Parameters->ParameterValues[j][2].f, 536 prog->Parameters->ParameterValues[j][3].f); 537 } 538 } 539 fflush(stdout); 540 } 541 #endif 542 543 /** 544 * Propagate some values from uniform backing storage to driver storage 545 * 546 * Values propagated from uniform backing storage to driver storage 547 * have all format / type conversions previously requested by the 548 * driver applied. This function is most often called by the 549 * implementations of \c glUniform1f, etc. and \c glUniformMatrix2f, 550 * etc. 551 * 552 * \param uni Uniform whose data is to be propagated to driver storage 553 * \param array_index If \c uni is an array, this is the element of 554 * the array to be propagated. 555 * \param count Number of array elements to propagate. 556 */ 557 extern "C" void 558 _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni, 559 unsigned array_index, 560 unsigned count) 561 { 562 unsigned i; 563 564 /* vector_elements and matrix_columns can be 0 for samplers. 565 */ 566 const unsigned components = MAX2(1, uni->type->vector_elements); 567 const unsigned vectors = MAX2(1, uni->type->matrix_columns); 568 const int dmul = uni->type->is_64bit() ? 2 : 1; 569 570 /* Store the data in the driver's requested type in the driver's storage 571 * areas. 572 */ 573 unsigned src_vector_byte_stride = components * 4 * dmul; 574 575 for (i = 0; i < uni->num_driver_storage; i++) { 576 struct gl_uniform_driver_storage *const store = &uni->driver_storage[i]; 577 uint8_t *dst = (uint8_t *) store->data; 578 const unsigned extra_stride = 579 store->element_stride - (vectors * store->vector_stride); 580 const uint8_t *src = 581 (uint8_t *) (&uni->storage[array_index * (dmul * components * vectors)].i); 582 583 #if 0 584 printf("%s: %p[%d] components=%u vectors=%u count=%u vector_stride=%u " 585 "extra_stride=%u\n", 586 __func__, dst, array_index, components, 587 vectors, count, store->vector_stride, extra_stride); 588 #endif 589 590 dst += array_index * store->element_stride; 591 592 switch (store->format) { 593 case uniform_native: { 594 unsigned j; 595 unsigned v; 596 597 if (src_vector_byte_stride == store->vector_stride) { 598 if (extra_stride) { 599 for (j = 0; j < count; j++) { 600 memcpy(dst, src, src_vector_byte_stride * vectors); 601 src += src_vector_byte_stride * vectors; 602 dst += store->vector_stride * vectors; 603 604 dst += extra_stride; 605 } 606 } else { 607 /* Unigine Heaven benchmark gets here */ 608 memcpy(dst, src, src_vector_byte_stride * vectors * count); 609 src += src_vector_byte_stride * vectors * count; 610 dst += store->vector_stride * vectors * count; 611 } 612 } else { 613 for (j = 0; j < count; j++) { 614 for (v = 0; v < vectors; v++) { 615 memcpy(dst, src, src_vector_byte_stride); 616 src += src_vector_byte_stride; 617 dst += store->vector_stride; 618 } 619 620 dst += extra_stride; 621 } 622 } 623 break; 624 } 625 626 case uniform_int_float: { 627 const int *isrc = (const int *) src; 628 unsigned j; 629 unsigned v; 630 unsigned c; 631 632 for (j = 0; j < count; j++) { 633 for (v = 0; v < vectors; v++) { 634 for (c = 0; c < components; c++) { 635 ((float *) dst)[c] = (float) *isrc; 636 isrc++; 637 } 638 639 dst += store->vector_stride; 640 } 641 642 dst += extra_stride; 643 } 644 break; 645 } 646 647 default: 648 assert(!"Should not get here."); 649 break; 650 } 651 } 652 } 653 654 655 /** 656 * Return printable string for a given GLSL_TYPE_x 657 */ 658 static const char * 659 glsl_type_name(enum glsl_base_type type) 660 { 661 switch (type) { 662 case GLSL_TYPE_UINT: 663 return "uint"; 664 case GLSL_TYPE_INT: 665 return "int"; 666 case GLSL_TYPE_FLOAT: 667 return "float"; 668 case GLSL_TYPE_DOUBLE: 669 return "double"; 670 case GLSL_TYPE_BOOL: 671 return "bool"; 672 case GLSL_TYPE_SAMPLER: 673 return "sampler"; 674 case GLSL_TYPE_IMAGE: 675 return "image"; 676 case GLSL_TYPE_ATOMIC_UINT: 677 return "atomic_uint"; 678 case GLSL_TYPE_STRUCT: 679 return "struct"; 680 case GLSL_TYPE_INTERFACE: 681 return "interface"; 682 case GLSL_TYPE_ARRAY: 683 return "array"; 684 case GLSL_TYPE_VOID: 685 return "void"; 686 case GLSL_TYPE_ERROR: 687 return "error"; 688 default: 689 return "other"; 690 } 691 } 692 693 694 /** 695 * Called via glUniform*() functions. 696 */ 697 extern "C" void 698 _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, 699 GLint location, GLsizei count, 700 const GLvoid *values, 701 enum glsl_base_type basicType, 702 unsigned src_components) 703 { 704 unsigned offset; 705 int size_mul = glsl_base_type_is_64bit(basicType) ? 2 : 1; 706 707 struct gl_uniform_storage *const uni = 708 validate_uniform_parameters(ctx, shProg, location, count, 709 &offset, "glUniform"); 710 if (uni == NULL) 711 return; 712 713 if (uni->type->is_matrix()) { 714 /* Can't set matrix uniforms (like mat4) with glUniform */ 715 _mesa_error(ctx, GL_INVALID_OPERATION, 716 "glUniform%u(uniform \"%s\"@%d is matrix)", 717 src_components, uni->name, location); 718 return; 719 } 720 721 /* Verify that the types are compatible. 722 */ 723 const unsigned components = uni->type->is_sampler() 724 ? 1 : uni->type->vector_elements; 725 726 if (components != src_components) { 727 /* glUniformN() must match float/vecN type */ 728 _mesa_error(ctx, GL_INVALID_OPERATION, 729 "glUniform%u(\"%s\"@%u has %u components, not %u)", 730 src_components, uni->name, location, 731 components, src_components); 732 return; 733 } 734 735 bool match; 736 switch (uni->type->base_type) { 737 case GLSL_TYPE_BOOL: 738 match = (basicType != GLSL_TYPE_DOUBLE); 739 break; 740 case GLSL_TYPE_SAMPLER: 741 match = (basicType == GLSL_TYPE_INT); 742 break; 743 case GLSL_TYPE_IMAGE: 744 match = (basicType == GLSL_TYPE_INT && _mesa_is_desktop_gl(ctx)); 745 break; 746 default: 747 match = (basicType == uni->type->base_type); 748 break; 749 } 750 751 if (!match) { 752 _mesa_error(ctx, GL_INVALID_OPERATION, 753 "glUniform%u(\"%s\"@%d is %s, not %s)", 754 src_components, uni->name, location, 755 glsl_type_name(uni->type->base_type), 756 glsl_type_name(basicType)); 757 return; 758 } 759 760 if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) { 761 log_uniform(values, basicType, components, 1, count, 762 false, shProg, location, uni); 763 } 764 765 /* Page 100 (page 116 of the PDF) of the OpenGL 3.0 spec says: 766 * 767 * "Setting a sampler's value to i selects texture image unit number 768 * i. The values of i range from zero to the implementation- dependent 769 * maximum supported number of texture image units." 770 * 771 * In addition, table 2.3, "Summary of GL errors," on page 17 (page 33 of 772 * the PDF) says: 773 * 774 * "Error Description Offending command 775 * ignored? 776 * ... 777 * INVALID_VALUE Numeric argument out of range Yes" 778 * 779 * Based on that, when an invalid sampler is specified, we generate a 780 * GL_INVALID_VALUE error and ignore the command. 781 */ 782 if (uni->type->is_sampler()) { 783 for (int i = 0; i < count; i++) { 784 const unsigned texUnit = ((unsigned *) values)[i]; 785 786 /* check that the sampler (tex unit index) is legal */ 787 if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) { 788 _mesa_error(ctx, GL_INVALID_VALUE, 789 "glUniform1i(invalid sampler/tex unit index for " 790 "uniform %d)", 791 location); 792 return; 793 } 794 } 795 /* We need to reset the validate flag on changes to samplers in case 796 * two different sampler types are set to the same texture unit. 797 */ 798 ctx->_Shader->Validated = GL_FALSE; 799 } 800 801 if (uni->type->is_image()) { 802 for (int i = 0; i < count; i++) { 803 const int unit = ((GLint *) values)[i]; 804 805 /* check that the image unit is legal */ 806 if (unit < 0 || unit >= (int)ctx->Const.MaxImageUnits) { 807 _mesa_error(ctx, GL_INVALID_VALUE, 808 "glUniform1i(invalid image unit index for uniform %d)", 809 location); 810 return; 811 } 812 } 813 } 814 815 /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: 816 * 817 * "When loading N elements starting at an arbitrary position k in a 818 * uniform declared as an array, elements k through k + N - 1 in the 819 * array will be replaced with the new values. Values for any array 820 * element that exceeds the highest array element index used, as 821 * reported by GetActiveUniform, will be ignored by the GL." 822 * 823 * Clamp 'count' to a valid value. Note that for non-arrays a count > 1 824 * will have already generated an error. 825 */ 826 if (uni->array_elements != 0) { 827 count = MIN2(count, (int) (uni->array_elements - offset)); 828 } 829 830 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); 831 832 /* Store the data in the "actual type" backing storage for the uniform. 833 */ 834 if (!uni->type->is_boolean()) { 835 memcpy(&uni->storage[size_mul * components * offset], values, 836 sizeof(uni->storage[0]) * components * count * size_mul); 837 } else { 838 const union gl_constant_value *src = 839 (const union gl_constant_value *) values; 840 union gl_constant_value *dst = &uni->storage[components * offset]; 841 const unsigned elems = components * count; 842 843 for (unsigned i = 0; i < elems; i++) { 844 if (basicType == GLSL_TYPE_FLOAT) { 845 dst[i].i = src[i].f != 0.0f ? ctx->Const.UniformBooleanTrue : 0; 846 } else { 847 dst[i].i = src[i].i != 0 ? ctx->Const.UniformBooleanTrue : 0; 848 } 849 } 850 } 851 852 _mesa_propagate_uniforms_to_driver_storage(uni, offset, count); 853 854 /* If the uniform is a sampler, do the extra magic necessary to propagate 855 * the changes through. 856 */ 857 if (uni->type->is_sampler()) { 858 bool flushed = false; 859 for (int i = 0; i < MESA_SHADER_STAGES; i++) { 860 struct gl_linked_shader *const sh = shProg->_LinkedShaders[i]; 861 862 /* If the shader stage doesn't use the sampler uniform, skip this. */ 863 if (!uni->opaque[i].active) 864 continue; 865 866 bool changed = false; 867 for (int j = 0; j < count; j++) { 868 unsigned unit = uni->opaque[i].index + offset + j; 869 if (sh->Program->SamplerUnits[unit] != ((unsigned *) values)[j]) { 870 sh->Program->SamplerUnits[unit] = ((unsigned *) values)[j]; 871 changed = true; 872 } 873 } 874 875 if (changed) { 876 if (!flushed) { 877 FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM); 878 flushed = true; 879 } 880 881 struct gl_program *const prog = sh->Program; 882 _mesa_update_shader_textures_used(shProg, prog); 883 if (ctx->Driver.SamplerUniformChange) 884 ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog); 885 } 886 } 887 } 888 889 /* If the uniform is an image, update the mapping from image 890 * uniforms to image units present in the shader data structure. 891 */ 892 if (uni->type->is_image()) { 893 for (int i = 0; i < MESA_SHADER_STAGES; i++) { 894 if (uni->opaque[i].active) { 895 struct gl_linked_shader *sh = shProg->_LinkedShaders[i]; 896 897 for (int j = 0; j < count; j++) 898 sh->Program->sh.ImageUnits[uni->opaque[i].index + offset + j] = 899 ((GLint *) values)[j]; 900 } 901 } 902 903 ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; 904 } 905 } 906 907 /** 908 * Called by glUniformMatrix*() functions. 909 * Note: cols=2, rows=4 ==> array[2] of vec4 910 */ 911 extern "C" void 912 _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, 913 GLuint cols, GLuint rows, 914 GLint location, GLsizei count, 915 GLboolean transpose, 916 const GLvoid *values, enum glsl_base_type basicType) 917 { 918 unsigned offset; 919 unsigned vectors; 920 unsigned components; 921 unsigned elements; 922 int size_mul; 923 struct gl_uniform_storage *const uni = 924 validate_uniform_parameters(ctx, shProg, location, count, 925 &offset, "glUniformMatrix"); 926 if (uni == NULL) 927 return; 928 929 if (!uni->type->is_matrix()) { 930 _mesa_error(ctx, GL_INVALID_OPERATION, 931 "glUniformMatrix(non-matrix uniform)"); 932 return; 933 } 934 935 assert(basicType == GLSL_TYPE_FLOAT || basicType == GLSL_TYPE_DOUBLE); 936 size_mul = basicType == GLSL_TYPE_DOUBLE ? 2 : 1; 937 938 assert(!uni->type->is_sampler()); 939 vectors = uni->type->matrix_columns; 940 components = uni->type->vector_elements; 941 942 /* Verify that the types are compatible. This is greatly simplified for 943 * matrices because they can only have a float base type. 944 */ 945 if (vectors != cols || components != rows) { 946 _mesa_error(ctx, GL_INVALID_OPERATION, 947 "glUniformMatrix(matrix size mismatch)"); 948 return; 949 } 950 951 /* GL_INVALID_VALUE is generated if `transpose' is not GL_FALSE. 952 * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml 953 */ 954 if (transpose) { 955 if (ctx->API == API_OPENGLES2 && ctx->Version < 30) { 956 _mesa_error(ctx, GL_INVALID_VALUE, 957 "glUniformMatrix(matrix transpose is not GL_FALSE)"); 958 return; 959 } 960 } 961 962 /* Section 2.11.7 (Uniform Variables) of the OpenGL 4.2 Core Profile spec 963 * says: 964 * 965 * "If any of the following conditions occur, an INVALID_OPERATION 966 * error is generated by the Uniform* commands, and no uniform values 967 * are changed: 968 * 969 * ... 970 * 971 * - if the uniform declared in the shader is not of type boolean and 972 * the type indicated in the name of the Uniform* command used does 973 * not match the type of the uniform" 974 * 975 * There are no Boolean matrix types, so we do not need to allow 976 * GLSL_TYPE_BOOL here (as _mesa_uniform does). 977 */ 978 if (uni->type->base_type != basicType) { 979 _mesa_error(ctx, GL_INVALID_OPERATION, 980 "glUniformMatrix%ux%u(\"%s\"@%d is %s, not %s)", 981 cols, rows, uni->name, location, 982 glsl_type_name(uni->type->base_type), 983 glsl_type_name(basicType)); 984 return; 985 } 986 987 if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) { 988 log_uniform(values, uni->type->base_type, components, vectors, count, 989 bool(transpose), shProg, location, uni); 990 } 991 992 /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: 993 * 994 * "When loading N elements starting at an arbitrary position k in a 995 * uniform declared as an array, elements k through k + N - 1 in the 996 * array will be replaced with the new values. Values for any array 997 * element that exceeds the highest array element index used, as 998 * reported by GetActiveUniform, will be ignored by the GL." 999 * 1000 * Clamp 'count' to a valid value. Note that for non-arrays a count > 1 1001 * will have already generated an error. 1002 */ 1003 if (uni->array_elements != 0) { 1004 count = MIN2(count, (int) (uni->array_elements - offset)); 1005 } 1006 1007 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); 1008 1009 /* Store the data in the "actual type" backing storage for the uniform. 1010 */ 1011 elements = components * vectors; 1012 1013 if (!transpose) { 1014 memcpy(&uni->storage[size_mul * elements * offset], values, 1015 sizeof(uni->storage[0]) * elements * count * size_mul); 1016 } else if (basicType == GLSL_TYPE_FLOAT) { 1017 /* Copy and transpose the matrix. 1018 */ 1019 const float *src = (const float *)values; 1020 float *dst = &uni->storage[elements * offset].f; 1021 1022 for (int i = 0; i < count; i++) { 1023 for (unsigned r = 0; r < rows; r++) { 1024 for (unsigned c = 0; c < cols; c++) { 1025 dst[(c * components) + r] = src[c + (r * vectors)]; 1026 } 1027 } 1028 1029 dst += elements; 1030 src += elements; 1031 } 1032 } else { 1033 assert(basicType == GLSL_TYPE_DOUBLE); 1034 const double *src = (const double *)values; 1035 double *dst = (double *)&uni->storage[elements * offset].f; 1036 1037 for (int i = 0; i < count; i++) { 1038 for (unsigned r = 0; r < rows; r++) { 1039 for (unsigned c = 0; c < cols; c++) { 1040 dst[(c * components) + r] = src[c + (r * vectors)]; 1041 } 1042 } 1043 1044 dst += elements; 1045 src += elements; 1046 } 1047 } 1048 1049 _mesa_propagate_uniforms_to_driver_storage(uni, offset, count); 1050 } 1051 1052 1053 extern "C" bool 1054 _mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg, 1055 char *errMsg, size_t errMsgLength) 1056 { 1057 /* Shader does not have samplers. */ 1058 if (shProg->data->NumUniformStorage == 0) 1059 return true; 1060 1061 if (!shProg->SamplersValidated) { 1062 _mesa_snprintf(errMsg, errMsgLength, 1063 "active samplers with a different type " 1064 "refer to the same texture image unit"); 1065 return false; 1066 } 1067 return true; 1068 } 1069 1070 extern "C" bool 1071 _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline) 1072 { 1073 /* Section 2.11.11 (Shader Execution), subheading "Validation," of the 1074 * OpenGL 4.1 spec says: 1075 * 1076 * "[INVALID_OPERATION] is generated by any command that transfers 1077 * vertices to the GL if: 1078 * 1079 * ... 1080 * 1081 * - Any two active samplers in the current program object are of 1082 * different types, but refer to the same texture image unit. 1083 * 1084 * - The number of active samplers in the program exceeds the 1085 * maximum number of texture image units allowed." 1086 */ 1087 1088 GLbitfield mask; 1089 GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; 1090 struct gl_linked_shader *shader; 1091 unsigned active_samplers = 0; 1092 const struct gl_shader_program **shProg = 1093 (const struct gl_shader_program **) pipeline->CurrentProgram; 1094 1095 1096 memset(TexturesUsed, 0, sizeof(TexturesUsed)); 1097 1098 for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) { 1099 if (!shProg[idx]) 1100 continue; 1101 1102 shader = shProg[idx]->_LinkedShaders[idx]; 1103 if (!shader || !shader->Program) 1104 continue; 1105 1106 mask = shader->Program->SamplersUsed; 1107 while (mask) { 1108 const int s = u_bit_scan(&mask); 1109 GLuint unit = shader->Program->SamplerUnits[s]; 1110 GLuint tgt = shader->Program->sh.SamplerTargets[s]; 1111 1112 /* FIXME: Samplers are initialized to 0 and Mesa doesn't do a 1113 * great job of eliminating unused uniforms currently so for now 1114 * don't throw an error if two sampler types both point to 0. 1115 */ 1116 if (unit == 0) 1117 continue; 1118 1119 if (TexturesUsed[unit] & ~(1 << tgt)) { 1120 pipeline->InfoLog = 1121 ralloc_asprintf(pipeline, 1122 "Program %d: " 1123 "Texture unit %d is accessed with 2 different types", 1124 shProg[idx]->Name, unit); 1125 return false; 1126 } 1127 1128 TexturesUsed[unit] |= (1 << tgt); 1129 } 1130 1131 active_samplers += shader->Program->info.num_textures; 1132 } 1133 1134 if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) { 1135 pipeline->InfoLog = 1136 ralloc_asprintf(pipeline, 1137 "the number of active samplers %d exceed the " 1138 "maximum %d", 1139 active_samplers, MAX_COMBINED_TEXTURE_IMAGE_UNITS); 1140 return false; 1141 } 1142 1143 return true; 1144 } 1145