1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Program.cpp: Implements the Program class. Implements GL program objects 16 // and related functionality. 17 18 #include "Program.h" 19 20 #include "main.h" 21 #include "Shader.h" 22 #include "utilities.h" 23 #include "common/debug.h" 24 #include "Shader/PixelShader.hpp" 25 #include "Shader/VertexShader.hpp" 26 27 #include <string> 28 #include <stdlib.h> 29 30 namespace gl 31 { 32 unsigned int Program::currentSerial = 1; 33 34 std::string str(int i) 35 { 36 char buffer[20]; 37 sprintf(buffer, "%d", i); 38 return buffer; 39 } 40 41 Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize) : type(type), precision(precision), name(name), arraySize(arraySize) 42 { 43 int bytes = UniformTypeSize(type) * size(); 44 data = new unsigned char[bytes]; 45 memset(data, 0, bytes); 46 dirty = true; 47 48 psRegisterIndex = -1; 49 vsRegisterIndex = -1; 50 } 51 52 Uniform::~Uniform() 53 { 54 delete[] data; 55 } 56 57 bool Uniform::isArray() const 58 { 59 return arraySize >= 1; 60 } 61 62 int Uniform::size() const 63 { 64 return arraySize > 0 ? arraySize : 1; 65 } 66 67 int Uniform::registerCount() const 68 { 69 return size() * VariableRowCount(type); 70 } 71 72 UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) : name(name), element(element), index(index) 73 { 74 } 75 76 Program::Program(ResourceManager *manager, GLuint handle) : resourceManager(manager), handle(handle), serial(issueSerial()) 77 { 78 device = getDevice(); 79 80 fragmentShader = 0; 81 vertexShader = 0; 82 pixelBinary = 0; 83 vertexBinary = 0; 84 85 infoLog = 0; 86 validated = false; 87 88 unlink(); 89 90 orphaned = false; 91 referenceCount = 0; 92 } 93 94 Program::~Program() 95 { 96 unlink(); 97 98 if(vertexShader) 99 { 100 vertexShader->release(); 101 } 102 103 if(fragmentShader) 104 { 105 fragmentShader->release(); 106 } 107 } 108 109 bool Program::attachShader(Shader *shader) 110 { 111 if(shader->getType() == GL_VERTEX_SHADER) 112 { 113 if(vertexShader) 114 { 115 return false; 116 } 117 118 vertexShader = (VertexShader*)shader; 119 vertexShader->addRef(); 120 } 121 else if(shader->getType() == GL_FRAGMENT_SHADER) 122 { 123 if(fragmentShader) 124 { 125 return false; 126 } 127 128 fragmentShader = (FragmentShader*)shader; 129 fragmentShader->addRef(); 130 } 131 else UNREACHABLE(shader->getType()); 132 133 return true; 134 } 135 136 bool Program::detachShader(Shader *shader) 137 { 138 if(shader->getType() == GL_VERTEX_SHADER) 139 { 140 if(vertexShader != shader) 141 { 142 return false; 143 } 144 145 vertexShader->release(); 146 vertexShader = 0; 147 } 148 else if(shader->getType() == GL_FRAGMENT_SHADER) 149 { 150 if(fragmentShader != shader) 151 { 152 return false; 153 } 154 155 fragmentShader->release(); 156 fragmentShader = 0; 157 } 158 else UNREACHABLE(shader->getType()); 159 160 return true; 161 } 162 163 int Program::getAttachedShadersCount() const 164 { 165 return (vertexShader ? 1 : 0) + (fragmentShader ? 1 : 0); 166 } 167 168 sw::PixelShader *Program::getPixelShader() 169 { 170 return pixelBinary; 171 } 172 173 sw::VertexShader *Program::getVertexShader() 174 { 175 return vertexBinary; 176 } 177 178 void Program::bindAttributeLocation(GLuint index, const char *name) 179 { 180 if(index < MAX_VERTEX_ATTRIBS) 181 { 182 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 183 { 184 attributeBinding[i].erase(name); 185 } 186 187 attributeBinding[index].insert(name); 188 } 189 } 190 191 GLuint Program::getAttributeLocation(const char *name) 192 { 193 if(name) 194 { 195 for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++) 196 { 197 if(linkedAttribute[index].name == std::string(name)) 198 { 199 return index; 200 } 201 } 202 } 203 204 return -1; 205 } 206 207 int Program::getAttributeStream(int attributeIndex) 208 { 209 ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS); 210 211 return attributeStream[attributeIndex]; 212 } 213 214 // Returns the index of the texture image unit (0-19) corresponding to a sampler index (0-15 for the pixel shader and 0-3 for the vertex shader) 215 GLint Program::getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex) 216 { 217 GLuint logicalTextureUnit = -1; 218 219 switch(type) 220 { 221 case sw::SAMPLER_PIXEL: 222 ASSERT(samplerIndex < sizeof(samplersPS) / sizeof(samplersPS[0])); 223 224 if(samplersPS[samplerIndex].active) 225 { 226 logicalTextureUnit = samplersPS[samplerIndex].logicalTextureUnit; 227 } 228 break; 229 case sw::SAMPLER_VERTEX: 230 ASSERT(samplerIndex < sizeof(samplersVS) / sizeof(samplersVS[0])); 231 232 if(samplersVS[samplerIndex].active) 233 { 234 logicalTextureUnit = samplersVS[samplerIndex].logicalTextureUnit; 235 } 236 break; 237 default: UNREACHABLE(type); 238 } 239 240 if(logicalTextureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS) 241 { 242 return logicalTextureUnit; 243 } 244 245 return -1; 246 } 247 248 // Returns the texture type for a given sampler type and index (0-15 for the pixel shader and 0-3 for the vertex shader) 249 TextureType Program::getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex) 250 { 251 switch(type) 252 { 253 case sw::SAMPLER_PIXEL: 254 ASSERT(samplerIndex < sizeof(samplersPS)/sizeof(samplersPS[0])); 255 ASSERT(samplersPS[samplerIndex].active); 256 return samplersPS[samplerIndex].textureType; 257 case sw::SAMPLER_VERTEX: 258 ASSERT(samplerIndex < sizeof(samplersVS)/sizeof(samplersVS[0])); 259 ASSERT(samplersVS[samplerIndex].active); 260 return samplersVS[samplerIndex].textureType; 261 default: UNREACHABLE(type); 262 } 263 264 return TEXTURE_2D; 265 } 266 267 GLint Program::getUniformLocation(std::string name) 268 { 269 int subscript = 0; 270 271 // Strip any trailing array operator and retrieve the subscript 272 size_t open = name.find_last_of('['); 273 size_t close = name.find_last_of(']'); 274 if(open != std::string::npos && close == name.length() - 1) 275 { 276 subscript = atoi(name.substr(open + 1).c_str()); 277 name.erase(open); 278 } 279 280 unsigned int numUniforms = uniformIndex.size(); 281 for(unsigned int location = 0; location < numUniforms; location++) 282 { 283 if(uniformIndex[location].name == name && 284 uniformIndex[location].element == subscript) 285 { 286 return location; 287 } 288 } 289 290 return -1; 291 } 292 293 bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) 294 { 295 if(location < 0 || location >= (int)uniformIndex.size()) 296 { 297 return false; 298 } 299 300 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 301 targetUniform->dirty = true; 302 303 int size = targetUniform->size(); 304 305 if(size == 1 && count > 1) 306 { 307 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 308 } 309 310 count = std::min(size - (int)uniformIndex[location].element, count); 311 312 if(targetUniform->type == GL_FLOAT) 313 { 314 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat), 315 v, sizeof(GLfloat) * count); 316 } 317 else if(targetUniform->type == GL_BOOL) 318 { 319 GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element; 320 321 for(int i = 0; i < count; i++) 322 { 323 if(v[i] == 0.0f) 324 { 325 boolParams[i] = GL_FALSE; 326 } 327 else 328 { 329 boolParams[i] = GL_TRUE; 330 } 331 } 332 } 333 else 334 { 335 return false; 336 } 337 338 return true; 339 } 340 341 bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) 342 { 343 if(location < 0 || location >= (int)uniformIndex.size()) 344 { 345 return false; 346 } 347 348 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 349 targetUniform->dirty = true; 350 351 int size = targetUniform->size(); 352 353 if(size == 1 && count > 1) 354 { 355 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 356 } 357 358 count = std::min(size - (int)uniformIndex[location].element, count); 359 360 if(targetUniform->type == GL_FLOAT_VEC2) 361 { 362 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 2, 363 v, 2 * sizeof(GLfloat) * count); 364 } 365 else if(targetUniform->type == GL_BOOL_VEC2) 366 { 367 GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * 2; 368 369 for(int i = 0; i < count * 2; i++) 370 { 371 if(v[i] == 0.0f) 372 { 373 boolParams[i] = GL_FALSE; 374 } 375 else 376 { 377 boolParams[i] = GL_TRUE; 378 } 379 } 380 } 381 else 382 { 383 return false; 384 } 385 386 return true; 387 } 388 389 bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) 390 { 391 if(location < 0 || location >= (int)uniformIndex.size()) 392 { 393 return false; 394 } 395 396 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 397 targetUniform->dirty = true; 398 399 int size = targetUniform->size(); 400 401 if(size == 1 && count > 1) 402 { 403 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 404 } 405 406 count = std::min(size - (int)uniformIndex[location].element, count); 407 408 if(targetUniform->type == GL_FLOAT_VEC3) 409 { 410 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 3, 411 v, 3 * sizeof(GLfloat) * count); 412 } 413 else if(targetUniform->type == GL_BOOL_VEC3) 414 { 415 GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * 3; 416 417 for(int i = 0; i < count * 3; i++) 418 { 419 if(v[i] == 0.0f) 420 { 421 boolParams[i] = GL_FALSE; 422 } 423 else 424 { 425 boolParams[i] = GL_TRUE; 426 } 427 } 428 } 429 else 430 { 431 return false; 432 } 433 434 return true; 435 } 436 437 bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) 438 { 439 if(location < 0 || location >= (int)uniformIndex.size()) 440 { 441 return false; 442 } 443 444 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 445 targetUniform->dirty = true; 446 447 int size = targetUniform->size(); 448 449 if(size == 1 && count > 1) 450 { 451 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 452 } 453 454 count = std::min(size - (int)uniformIndex[location].element, count); 455 456 if(targetUniform->type == GL_FLOAT_VEC4) 457 { 458 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 4, 459 v, 4 * sizeof(GLfloat) * count); 460 } 461 else if(targetUniform->type == GL_BOOL_VEC4) 462 { 463 GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * 4; 464 465 for(int i = 0; i < count * 4; i++) 466 { 467 if(v[i] == 0.0f) 468 { 469 boolParams[i] = GL_FALSE; 470 } 471 else 472 { 473 boolParams[i] = GL_TRUE; 474 } 475 } 476 } 477 else 478 { 479 return false; 480 } 481 482 return true; 483 } 484 485 bool Program::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) 486 { 487 if(location < 0 || location >= (int)uniformIndex.size()) 488 { 489 return false; 490 } 491 492 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 493 targetUniform->dirty = true; 494 495 if(targetUniform->type != GL_FLOAT_MAT2) 496 { 497 return false; 498 } 499 500 int size = targetUniform->size(); 501 502 if(size == 1 && count > 1) 503 { 504 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 505 } 506 507 count = std::min(size - (int)uniformIndex[location].element, count); 508 509 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 4, 510 value, 4 * sizeof(GLfloat) * count); 511 512 return true; 513 } 514 515 bool Program::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) 516 { 517 if(location < 0 || location >= (int)uniformIndex.size()) 518 { 519 return false; 520 } 521 522 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 523 targetUniform->dirty = true; 524 525 if(targetUniform->type != GL_FLOAT_MAT3) 526 { 527 return false; 528 } 529 530 int size = targetUniform->size(); 531 532 if(size == 1 && count > 1) 533 { 534 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 535 } 536 537 count = std::min(size - (int)uniformIndex[location].element, count); 538 539 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 9, 540 value, 9 * sizeof(GLfloat) * count); 541 542 return true; 543 } 544 545 bool Program::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) 546 { 547 if(location < 0 || location >= (int)uniformIndex.size()) 548 { 549 return false; 550 } 551 552 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 553 targetUniform->dirty = true; 554 555 if(targetUniform->type != GL_FLOAT_MAT4) 556 { 557 return false; 558 } 559 560 int size = targetUniform->size(); 561 562 if(size == 1 && count > 1) 563 { 564 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 565 } 566 567 count = std::min(size - (int)uniformIndex[location].element, count); 568 569 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 16, 570 value, 16 * sizeof(GLfloat) * count); 571 572 return true; 573 } 574 575 bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v) 576 { 577 if(location < 0 || location >= (int)uniformIndex.size()) 578 { 579 return false; 580 } 581 582 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 583 targetUniform->dirty = true; 584 585 int size = targetUniform->size(); 586 587 if(size == 1 && count > 1) 588 { 589 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 590 } 591 592 count = std::min(size - (int)uniformIndex[location].element, count); 593 594 if(targetUniform->type == GL_INT || 595 targetUniform->type == GL_SAMPLER_2D || 596 targetUniform->type == GL_SAMPLER_CUBE) 597 { 598 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint), 599 v, sizeof(GLint) * count); 600 } 601 else if(targetUniform->type == GL_BOOL) 602 { 603 GLboolean *boolParams = new GLboolean[count]; 604 605 for(int i = 0; i < count; i++) 606 { 607 if(v[i] == 0) 608 { 609 boolParams[i] = GL_FALSE; 610 } 611 else 612 { 613 boolParams[i] = GL_TRUE; 614 } 615 } 616 617 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean), 618 boolParams, sizeof(GLboolean) * count); 619 620 delete[] boolParams; 621 } 622 else 623 { 624 return false; 625 } 626 627 return true; 628 } 629 630 bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v) 631 { 632 if(location < 0 || location >= (int)uniformIndex.size()) 633 { 634 return false; 635 } 636 637 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 638 targetUniform->dirty = true; 639 640 int size = targetUniform->size(); 641 642 if(size == 1 && count > 1) 643 { 644 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 645 } 646 647 count = std::min(size - (int)uniformIndex[location].element, count); 648 649 if(targetUniform->type == GL_INT_VEC2) 650 { 651 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint) * 2, 652 v, 2 * sizeof(GLint) * count); 653 } 654 else if(targetUniform->type == GL_BOOL_VEC2) 655 { 656 GLboolean *boolParams = new GLboolean[count * 2]; 657 658 for(int i = 0; i < count * 2; i++) 659 { 660 if(v[i] == 0) 661 { 662 boolParams[i] = GL_FALSE; 663 } 664 else 665 { 666 boolParams[i] = GL_TRUE; 667 } 668 } 669 670 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean) * 2, 671 boolParams, 2 * sizeof(GLboolean) * count); 672 673 delete[] boolParams; 674 } 675 else 676 { 677 return false; 678 } 679 680 return true; 681 } 682 683 bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v) 684 { 685 if(location < 0 || location >= (int)uniformIndex.size()) 686 { 687 return false; 688 } 689 690 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 691 targetUniform->dirty = true; 692 693 int size = targetUniform->size(); 694 695 if(size == 1 && count > 1) 696 { 697 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 698 } 699 700 count = std::min(size - (int)uniformIndex[location].element, count); 701 702 if(targetUniform->type == GL_INT_VEC3) 703 { 704 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint) * 3, 705 v, 3 * sizeof(GLint) * count); 706 } 707 else if(targetUniform->type == GL_BOOL_VEC3) 708 { 709 GLboolean *boolParams = new GLboolean[count * 3]; 710 711 for(int i = 0; i < count * 3; i++) 712 { 713 if(v[i] == 0) 714 { 715 boolParams[i] = GL_FALSE; 716 } 717 else 718 { 719 boolParams[i] = GL_TRUE; 720 } 721 } 722 723 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean) * 3, 724 boolParams, 3 * sizeof(GLboolean) * count); 725 726 delete[] boolParams; 727 } 728 else 729 { 730 return false; 731 } 732 733 return true; 734 } 735 736 bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v) 737 { 738 if(location < 0 || location >= (int)uniformIndex.size()) 739 { 740 return false; 741 } 742 743 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 744 targetUniform->dirty = true; 745 746 int size = targetUniform->size(); 747 748 if(size == 1 && count > 1) 749 { 750 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 751 } 752 753 count = std::min(size - (int)uniformIndex[location].element, count); 754 755 if(targetUniform->type == GL_INT_VEC4) 756 { 757 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint) * 4, 758 v, 4 * sizeof(GLint) * count); 759 } 760 else if(targetUniform->type == GL_BOOL_VEC4) 761 { 762 GLboolean *boolParams = new GLboolean[count * 4]; 763 764 for(int i = 0; i < count * 4; i++) 765 { 766 if(v[i] == 0) 767 { 768 boolParams[i] = GL_FALSE; 769 } 770 else 771 { 772 boolParams[i] = GL_TRUE; 773 } 774 } 775 776 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean) * 4, 777 boolParams, 4 * sizeof(GLboolean) * count); 778 779 delete[] boolParams; 780 } 781 else 782 { 783 return false; 784 } 785 786 return true; 787 } 788 789 bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params) 790 { 791 if(location < 0 || location >= (int)uniformIndex.size()) 792 { 793 return false; 794 } 795 796 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 797 unsigned int count = UniformComponentCount(targetUniform->type); 798 799 // Sized query - ensure the provided buffer is large enough 800 if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLfloat)) 801 { 802 return false; 803 } 804 805 switch(UniformComponentType(targetUniform->type)) 806 { 807 case GL_BOOL: 808 { 809 GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * count; 810 811 for(unsigned int i = 0; i < count; i++) 812 { 813 params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f; 814 } 815 } 816 break; 817 case GL_FLOAT: 818 memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLfloat), 819 count * sizeof(GLfloat)); 820 break; 821 case GL_INT: 822 { 823 GLint *intParams = (GLint*)targetUniform->data + uniformIndex[location].element * count; 824 825 for(unsigned int i = 0; i < count; i++) 826 { 827 params[i] = (float)intParams[i]; 828 } 829 } 830 break; 831 default: UNREACHABLE(targetUniform->type); 832 } 833 834 return true; 835 } 836 837 bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params) 838 { 839 if(location < 0 || location >= (int)uniformIndex.size()) 840 { 841 return false; 842 } 843 844 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 845 unsigned int count = UniformComponentCount(targetUniform->type); 846 847 // Sized query - ensure the provided buffer is large enough 848 if(bufSize && static_cast<unsigned int>(*bufSize) < count *sizeof(GLint)) 849 { 850 return false; 851 } 852 853 switch(UniformComponentType(targetUniform->type)) 854 { 855 case GL_BOOL: 856 { 857 GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count; 858 859 for(unsigned int i = 0; i < count; i++) 860 { 861 params[i] = (GLint)boolParams[i]; 862 } 863 } 864 break; 865 case GL_FLOAT: 866 { 867 GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count; 868 869 for(unsigned int i = 0; i < count; i++) 870 { 871 params[i] = (GLint)floatParams[i]; 872 } 873 } 874 break; 875 case GL_INT: 876 memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLint), 877 count * sizeof(GLint)); 878 break; 879 default: UNREACHABLE(targetUniform->type); 880 } 881 882 return true; 883 } 884 885 void Program::dirtyAllUniforms() 886 { 887 unsigned int numUniforms = uniforms.size(); 888 for(unsigned int index = 0; index < numUniforms; index++) 889 { 890 uniforms[index]->dirty = true; 891 } 892 } 893 894 // Applies all the uniforms set for this program object to the device 895 void Program::applyUniforms() 896 { 897 unsigned int numUniforms = uniformIndex.size(); 898 for(unsigned int location = 0; location < numUniforms; location++) 899 { 900 if(uniformIndex[location].element != 0) 901 { 902 continue; 903 } 904 905 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 906 907 if(targetUniform->dirty) 908 { 909 int size = targetUniform->size(); 910 GLfloat *f = (GLfloat*)targetUniform->data; 911 GLint *i = (GLint*)targetUniform->data; 912 GLboolean *b = (GLboolean*)targetUniform->data; 913 914 switch(targetUniform->type) 915 { 916 case GL_BOOL: applyUniform1bv(location, size, b); break; 917 case GL_BOOL_VEC2: applyUniform2bv(location, size, b); break; 918 case GL_BOOL_VEC3: applyUniform3bv(location, size, b); break; 919 case GL_BOOL_VEC4: applyUniform4bv(location, size, b); break; 920 case GL_FLOAT: applyUniform1fv(location, size, f); break; 921 case GL_FLOAT_VEC2: applyUniform2fv(location, size, f); break; 922 case GL_FLOAT_VEC3: applyUniform3fv(location, size, f); break; 923 case GL_FLOAT_VEC4: applyUniform4fv(location, size, f); break; 924 case GL_FLOAT_MAT2: applyUniformMatrix2fv(location, size, f); break; 925 case GL_FLOAT_MAT3: applyUniformMatrix3fv(location, size, f); break; 926 case GL_FLOAT_MAT4: applyUniformMatrix4fv(location, size, f); break; 927 case GL_SAMPLER_2D: 928 case GL_SAMPLER_CUBE: 929 case GL_INT: applyUniform1iv(location, size, i); break; 930 case GL_INT_VEC2: applyUniform2iv(location, size, i); break; 931 case GL_INT_VEC3: applyUniform3iv(location, size, i); break; 932 case GL_INT_VEC4: applyUniform4iv(location, size, i); break; 933 default: 934 UNREACHABLE(targetUniform->type); 935 } 936 937 targetUniform->dirty = false; 938 } 939 } 940 } 941 942 // Packs varyings into generic varying registers. 943 // Returns the number of used varying registers, or -1 if unsuccesful 944 int Program::packVaryings(const glsl::Varying *packing[][4]) 945 { 946 for(glsl::VaryingList::iterator varying = fragmentShader->varyings.begin(); varying != fragmentShader->varyings.end(); varying++) 947 { 948 int n = VariableRowCount(varying->type) * varying->size(); 949 int m = VariableColumnCount(varying->type); 950 bool success = false; 951 952 if(m == 2 || m == 3 || m == 4) 953 { 954 for(int r = 0; r <= MAX_VARYING_VECTORS - n && !success; r++) 955 { 956 bool available = true; 957 958 for(int y = 0; y < n && available; y++) 959 { 960 for(int x = 0; x < m && available; x++) 961 { 962 if(packing[r + y][x]) 963 { 964 available = false; 965 } 966 } 967 } 968 969 if(available) 970 { 971 varying->reg = r; 972 varying->col = 0; 973 974 for(int y = 0; y < n; y++) 975 { 976 for(int x = 0; x < m; x++) 977 { 978 packing[r + y][x] = &*varying; 979 } 980 } 981 982 success = true; 983 } 984 } 985 986 if(!success && m == 2) 987 { 988 for(int r = MAX_VARYING_VECTORS - n; r >= 0 && !success; r--) 989 { 990 bool available = true; 991 992 for(int y = 0; y < n && available; y++) 993 { 994 for(int x = 2; x < 4 && available; x++) 995 { 996 if(packing[r + y][x]) 997 { 998 available = false; 999 } 1000 } 1001 } 1002 1003 if(available) 1004 { 1005 varying->reg = r; 1006 varying->col = 2; 1007 1008 for(int y = 0; y < n; y++) 1009 { 1010 for(int x = 2; x < 4; x++) 1011 { 1012 packing[r + y][x] = &*varying; 1013 } 1014 } 1015 1016 success = true; 1017 } 1018 } 1019 } 1020 } 1021 else if(m == 1) 1022 { 1023 int space[4] = {0}; 1024 1025 for(int y = 0; y < MAX_VARYING_VECTORS; y++) 1026 { 1027 for(int x = 0; x < 4; x++) 1028 { 1029 space[x] += packing[y][x] ? 0 : 1; 1030 } 1031 } 1032 1033 int column = 0; 1034 1035 for(int x = 0; x < 4; x++) 1036 { 1037 if(space[x] >= n && space[x] < space[column]) 1038 { 1039 column = x; 1040 } 1041 } 1042 1043 if(space[column] >= n) 1044 { 1045 for(int r = 0; r < MAX_VARYING_VECTORS; r++) 1046 { 1047 if(!packing[r][column]) 1048 { 1049 varying->reg = r; 1050 1051 for(int y = r; y < r + n; y++) 1052 { 1053 packing[y][column] = &*varying; 1054 } 1055 1056 break; 1057 } 1058 } 1059 1060 varying->col = column; 1061 1062 success = true; 1063 } 1064 } 1065 else UNREACHABLE(m); 1066 1067 if(!success) 1068 { 1069 appendToInfoLog("Could not pack varying %s", varying->name.c_str()); 1070 1071 return -1; 1072 } 1073 } 1074 1075 // Return the number of used registers 1076 int registers = 0; 1077 1078 for(int r = 0; r < MAX_VARYING_VECTORS; r++) 1079 { 1080 if(packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3]) 1081 { 1082 registers++; 1083 } 1084 } 1085 1086 return registers; 1087 } 1088 1089 bool Program::linkVaryings() 1090 { 1091 for(glsl::VaryingList::iterator input = fragmentShader->varyings.begin(); input != fragmentShader->varyings.end(); input++) 1092 { 1093 bool matched = false; 1094 1095 for(glsl::VaryingList::iterator output = vertexShader->varyings.begin(); output != vertexShader->varyings.end(); output++) 1096 { 1097 if(output->name == input->name) 1098 { 1099 if(output->type != input->type || output->size() != input->size()) 1100 { 1101 appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str()); 1102 1103 return false; 1104 } 1105 1106 matched = true; 1107 break; 1108 } 1109 } 1110 1111 if(!matched) 1112 { 1113 appendToInfoLog("Fragment varying %s does not match any vertex varying", input->name.c_str()); 1114 1115 return false; 1116 } 1117 } 1118 1119 glsl::VaryingList &psVaryings = fragmentShader->varyings; 1120 glsl::VaryingList &vsVaryings = vertexShader->varyings; 1121 1122 for(glsl::VaryingList::iterator output = vsVaryings.begin(); output != vsVaryings.end(); output++) 1123 { 1124 for(glsl::VaryingList::iterator input = psVaryings.begin(); input != psVaryings.end(); input++) 1125 { 1126 if(output->name == input->name) 1127 { 1128 int in = input->reg; 1129 int out = output->reg; 1130 int components = VariableColumnCount(output->type); 1131 int registers = VariableRowCount(output->type) * output->size(); 1132 1133 ASSERT(in >= 0); 1134 1135 if(in + registers > MAX_VARYING_VECTORS) 1136 { 1137 appendToInfoLog("Too many varyings"); 1138 return false; 1139 } 1140 1141 if(out >= 0) 1142 { 1143 if(out + registers > MAX_VARYING_VECTORS) 1144 { 1145 appendToInfoLog("Too many varyings"); 1146 return false; 1147 } 1148 1149 for(int i = 0; i < registers; i++) 1150 { 1151 vertexBinary->setOutput(out + i, components, sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i)); 1152 } 1153 } 1154 else // Vertex varying is declared but not written to 1155 { 1156 for(int i = 0; i < registers; i++) 1157 { 1158 pixelBinary->setInput(in + i, components, sw::Shader::Semantic()); 1159 } 1160 } 1161 1162 break; 1163 } 1164 } 1165 } 1166 1167 return true; 1168 } 1169 1170 // Links the code of the vertex and pixel shader by matching up their varyings, 1171 // compiling them into binaries, determining the attribute mappings, and collecting 1172 // a list of uniforms 1173 void Program::link() 1174 { 1175 unlink(); 1176 1177 if(!fragmentShader || !fragmentShader->isCompiled()) 1178 { 1179 return; 1180 } 1181 1182 if(!vertexShader || !vertexShader->isCompiled()) 1183 { 1184 return; 1185 } 1186 1187 vertexBinary = new sw::VertexShader(vertexShader->getVertexShader()); 1188 pixelBinary = new sw::PixelShader(fragmentShader->getPixelShader()); 1189 1190 if(!linkVaryings()) 1191 { 1192 return; 1193 } 1194 1195 if(!linkAttributes()) 1196 { 1197 return; 1198 } 1199 1200 if(!linkUniforms(fragmentShader)) 1201 { 1202 return; 1203 } 1204 1205 if(!linkUniforms(vertexShader)) 1206 { 1207 return; 1208 } 1209 1210 linked = true; // Success 1211 } 1212 1213 // Determines the mapping between GL attributes and vertex stream usage indices 1214 bool Program::linkAttributes() 1215 { 1216 unsigned int usedLocations = 0; 1217 1218 // Link attributes that have a binding location 1219 for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); attribute++) 1220 { 1221 int location = getAttributeBinding(attribute->name); 1222 1223 if(location != -1) // Set by glBindAttribLocation 1224 { 1225 if(!linkedAttribute[location].name.empty()) 1226 { 1227 // Multiple active attributes bound to the same location; not an error 1228 } 1229 1230 linkedAttribute[location] = *attribute; 1231 1232 int rows = VariableRowCount(attribute->type); 1233 1234 if(rows + location > MAX_VERTEX_ATTRIBS) 1235 { 1236 appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location); 1237 return false; 1238 } 1239 1240 for(int i = 0; i < rows; i++) 1241 { 1242 usedLocations |= 1 << (location + i); 1243 } 1244 } 1245 } 1246 1247 // Link attributes that don't have a binding location 1248 for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); attribute++) 1249 { 1250 int location = getAttributeBinding(attribute->name); 1251 1252 if(location == -1) // Not set by glBindAttribLocation 1253 { 1254 int rows = VariableRowCount(attribute->type); 1255 int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS); 1256 1257 if(availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS) 1258 { 1259 appendToInfoLog("Too many active attributes (%s)", attribute->name.c_str()); 1260 return false; // Fail to link 1261 } 1262 1263 linkedAttribute[availableIndex] = *attribute; 1264 } 1265 } 1266 1267 for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; ) 1268 { 1269 int index = vertexShader->getSemanticIndex(linkedAttribute[attributeIndex].name); 1270 int rows = std::max(VariableRowCount(linkedAttribute[attributeIndex].type), 1); 1271 1272 for(int r = 0; r < rows; r++) 1273 { 1274 attributeStream[attributeIndex++] = index++; 1275 } 1276 } 1277 1278 return true; 1279 } 1280 1281 int Program::getAttributeBinding(const std::string &name) 1282 { 1283 for(int location = 0; location < MAX_VERTEX_ATTRIBS; location++) 1284 { 1285 if(attributeBinding[location].find(name) != attributeBinding[location].end()) 1286 { 1287 return location; 1288 } 1289 } 1290 1291 return -1; 1292 } 1293 1294 bool Program::linkUniforms(Shader *shader) 1295 { 1296 const glsl::ActiveUniforms &activeUniforms = shader->activeUniforms; 1297 1298 for(unsigned int uniformIndex = 0; uniformIndex < activeUniforms.size(); uniformIndex++) 1299 { 1300 const glsl::Uniform &uniform = activeUniforms[uniformIndex]; 1301 1302 if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex)) 1303 { 1304 return false; 1305 } 1306 } 1307 1308 return true; 1309 } 1310 1311 bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex) 1312 { 1313 if(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE) 1314 { 1315 int index = registerIndex; 1316 1317 do 1318 { 1319 if(shader == GL_VERTEX_SHADER) 1320 { 1321 if(index < MAX_VERTEX_TEXTURE_IMAGE_UNITS) 1322 { 1323 samplersVS[index].active = true; 1324 samplersVS[index].textureType = (type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D; 1325 samplersVS[index].logicalTextureUnit = 0; 1326 } 1327 else 1328 { 1329 appendToInfoLog("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", MAX_VERTEX_TEXTURE_IMAGE_UNITS); 1330 return false; 1331 } 1332 } 1333 else if(shader == GL_FRAGMENT_SHADER) 1334 { 1335 if(index < MAX_TEXTURE_IMAGE_UNITS) 1336 { 1337 samplersPS[index].active = true; 1338 samplersPS[index].textureType = (type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D; 1339 samplersPS[index].logicalTextureUnit = 0; 1340 } 1341 else 1342 { 1343 appendToInfoLog("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS); 1344 return false; 1345 } 1346 } 1347 else UNREACHABLE(shader); 1348 1349 index++; 1350 } 1351 while(index < registerIndex + static_cast<int>(arraySize)); 1352 } 1353 1354 Uniform *uniform = 0; 1355 GLint location = getUniformLocation(name); 1356 1357 if(location >= 0) // Previously defined, types must match 1358 { 1359 uniform = uniforms[uniformIndex[location].index]; 1360 1361 if(uniform->type != type) 1362 { 1363 appendToInfoLog("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str()); 1364 return false; 1365 } 1366 1367 if(uniform->precision != precision) 1368 { 1369 appendToInfoLog("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str()); 1370 return false; 1371 } 1372 } 1373 else 1374 { 1375 uniform = new Uniform(type, precision, name, arraySize); 1376 } 1377 1378 if(!uniform) 1379 { 1380 return false; 1381 } 1382 1383 if(shader == GL_VERTEX_SHADER) 1384 { 1385 uniform->vsRegisterIndex = registerIndex; 1386 } 1387 else if(shader == GL_FRAGMENT_SHADER) 1388 { 1389 uniform->psRegisterIndex = registerIndex; 1390 } 1391 else UNREACHABLE(shader); 1392 1393 if(location == -1) // Not previously defined 1394 { 1395 uniforms.push_back(uniform); 1396 unsigned int index = uniforms.size() - 1; 1397 1398 for(int i = 0; i < uniform->size(); i++) 1399 { 1400 uniformIndex.push_back(UniformLocation(name, i, index)); 1401 } 1402 } 1403 1404 if(shader == GL_VERTEX_SHADER) 1405 { 1406 if(registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS) 1407 { 1408 appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS); 1409 return false; 1410 } 1411 } 1412 else if(shader == GL_FRAGMENT_SHADER) 1413 { 1414 if(registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS) 1415 { 1416 appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS); 1417 return false; 1418 } 1419 } 1420 else UNREACHABLE(shader); 1421 1422 return true; 1423 } 1424 1425 bool Program::applyUniform1bv(GLint location, GLsizei count, const GLboolean *v) 1426 { 1427 int vector[MAX_UNIFORM_VECTORS][4]; 1428 1429 for(int i = 0; i < count; i++) 1430 { 1431 vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 1432 vector[i][1] = 0; 1433 vector[i][2] = 0; 1434 vector[i][3] = 0; 1435 1436 v += 1; 1437 } 1438 1439 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1440 1441 if(targetUniform->psRegisterIndex != -1) 1442 { 1443 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount()); 1444 } 1445 1446 if(targetUniform->vsRegisterIndex != -1) 1447 { 1448 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount()); 1449 } 1450 1451 return true; 1452 } 1453 1454 bool Program::applyUniform2bv(GLint location, GLsizei count, const GLboolean *v) 1455 { 1456 int vector[MAX_UNIFORM_VECTORS][4]; 1457 1458 for(int i = 0; i < count; i++) 1459 { 1460 vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 1461 vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 1462 vector[i][2] = 0; 1463 vector[i][3] = 0; 1464 1465 v += 2; 1466 } 1467 1468 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1469 1470 if(targetUniform->psRegisterIndex != -1) 1471 { 1472 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount()); 1473 } 1474 1475 if(targetUniform->vsRegisterIndex != -1) 1476 { 1477 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount()); 1478 } 1479 1480 return true; 1481 } 1482 1483 bool Program::applyUniform3bv(GLint location, GLsizei count, const GLboolean *v) 1484 { 1485 int vector[MAX_UNIFORM_VECTORS][4]; 1486 1487 for(int i = 0; i < count; i++) 1488 { 1489 vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 1490 vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 1491 vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 1492 vector[i][3] = 0; 1493 1494 v += 3; 1495 } 1496 1497 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1498 1499 if(targetUniform->psRegisterIndex != -1) 1500 { 1501 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount()); 1502 } 1503 1504 if(targetUniform->vsRegisterIndex != -1) 1505 { 1506 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount()); 1507 } 1508 1509 return true; 1510 } 1511 1512 bool Program::applyUniform4bv(GLint location, GLsizei count, const GLboolean *v) 1513 { 1514 int vector[MAX_UNIFORM_VECTORS][4]; 1515 1516 for(int i = 0; i < count; i++) 1517 { 1518 vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 1519 vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 1520 vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 1521 vector[i][3] = (v[3] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 1522 1523 v += 4; 1524 } 1525 1526 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1527 1528 if(targetUniform->psRegisterIndex != -1) 1529 { 1530 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount()); 1531 } 1532 1533 if(targetUniform->vsRegisterIndex != -1) 1534 { 1535 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount()); 1536 } 1537 1538 return true; 1539 } 1540 1541 bool Program::applyUniform1fv(GLint location, GLsizei count, const GLfloat *v) 1542 { 1543 float vector[MAX_UNIFORM_VECTORS][4]; 1544 1545 for(int i = 0; i < count; i++) 1546 { 1547 vector[i][0] = v[0]; 1548 vector[i][1] = 0; 1549 vector[i][2] = 0; 1550 vector[i][3] = 0; 1551 1552 v += 1; 1553 } 1554 1555 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1556 1557 if(targetUniform->psRegisterIndex != -1) 1558 { 1559 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount()); 1560 } 1561 1562 if(targetUniform->vsRegisterIndex != -1) 1563 { 1564 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount()); 1565 } 1566 1567 return true; 1568 } 1569 1570 bool Program::applyUniform2fv(GLint location, GLsizei count, const GLfloat *v) 1571 { 1572 float vector[MAX_UNIFORM_VECTORS][4]; 1573 1574 for(int i = 0; i < count; i++) 1575 { 1576 vector[i][0] = v[0]; 1577 vector[i][1] = v[1]; 1578 vector[i][2] = 0; 1579 vector[i][3] = 0; 1580 1581 v += 2; 1582 } 1583 1584 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1585 1586 if(targetUniform->psRegisterIndex != -1) 1587 { 1588 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount()); 1589 } 1590 1591 if(targetUniform->vsRegisterIndex != -1) 1592 { 1593 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount()); 1594 } 1595 1596 return true; 1597 } 1598 1599 bool Program::applyUniform3fv(GLint location, GLsizei count, const GLfloat *v) 1600 { 1601 float vector[MAX_UNIFORM_VECTORS][4]; 1602 1603 for(int i = 0; i < count; i++) 1604 { 1605 vector[i][0] = v[0]; 1606 vector[i][1] = v[1]; 1607 vector[i][2] = v[2]; 1608 vector[i][3] = 0; 1609 1610 v += 3; 1611 } 1612 1613 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1614 1615 if(targetUniform->psRegisterIndex != -1) 1616 { 1617 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount()); 1618 } 1619 1620 if(targetUniform->vsRegisterIndex != -1) 1621 { 1622 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount()); 1623 } 1624 1625 return true; 1626 } 1627 1628 bool Program::applyUniform4fv(GLint location, GLsizei count, const GLfloat *v) 1629 { 1630 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1631 1632 if(targetUniform->psRegisterIndex != -1) 1633 { 1634 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)v, targetUniform->registerCount()); 1635 } 1636 1637 if(targetUniform->vsRegisterIndex != -1) 1638 { 1639 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)v, targetUniform->registerCount()); 1640 } 1641 1642 return true; 1643 } 1644 1645 bool Program::applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) 1646 { 1647 float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4]; 1648 1649 for(int i = 0; i < count; i++) 1650 { 1651 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = 0; matrix[i][0][3] = 0; 1652 matrix[i][1][0] = value[2]; matrix[i][1][1] = value[3]; matrix[i][1][2] = 0; matrix[i][1][3] = 0; 1653 1654 value += 4; 1655 } 1656 1657 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1658 1659 if(targetUniform->psRegisterIndex != -1) 1660 { 1661 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)matrix, targetUniform->registerCount()); 1662 } 1663 1664 if(targetUniform->vsRegisterIndex != -1) 1665 { 1666 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)matrix, targetUniform->registerCount()); 1667 } 1668 1669 return true; 1670 } 1671 1672 bool Program::applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) 1673 { 1674 float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4]; 1675 1676 for(int i = 0; i < count; i++) 1677 { 1678 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = value[2]; matrix[i][0][3] = 0; 1679 matrix[i][1][0] = value[3]; matrix[i][1][1] = value[4]; matrix[i][1][2] = value[5]; matrix[i][1][3] = 0; 1680 matrix[i][2][0] = value[6]; matrix[i][2][1] = value[7]; matrix[i][2][2] = value[8]; matrix[i][2][3] = 0; 1681 1682 value += 9; 1683 } 1684 1685 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1686 1687 if(targetUniform->psRegisterIndex != -1) 1688 { 1689 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)matrix, targetUniform->registerCount()); 1690 } 1691 1692 if(targetUniform->vsRegisterIndex != -1) 1693 { 1694 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)matrix, targetUniform->registerCount()); 1695 } 1696 1697 return true; 1698 } 1699 1700 bool Program::applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) 1701 { 1702 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1703 1704 if(targetUniform->psRegisterIndex != -1) 1705 { 1706 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)value, targetUniform->registerCount()); 1707 } 1708 1709 if(targetUniform->vsRegisterIndex != -1) 1710 { 1711 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)value, targetUniform->registerCount()); 1712 } 1713 1714 return true; 1715 } 1716 1717 bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v) 1718 { 1719 float vector[MAX_UNIFORM_VECTORS][4]; 1720 1721 for(int i = 0; i < count; i++) 1722 { 1723 vector[i][0] = (float)v[i]; 1724 vector[i][1] = 0; 1725 vector[i][2] = 0; 1726 vector[i][3] = 0; 1727 } 1728 1729 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1730 1731 if(targetUniform->psRegisterIndex != -1) 1732 { 1733 if(targetUniform->type == GL_SAMPLER_2D || 1734 targetUniform->type == GL_SAMPLER_CUBE) 1735 { 1736 for(int i = 0; i < count; i++) 1737 { 1738 unsigned int samplerIndex = targetUniform->psRegisterIndex + i; 1739 1740 if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS) 1741 { 1742 ASSERT(samplersPS[samplerIndex].active); 1743 samplersPS[samplerIndex].logicalTextureUnit = v[i]; 1744 } 1745 } 1746 } 1747 else 1748 { 1749 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount()); 1750 } 1751 } 1752 1753 if(targetUniform->vsRegisterIndex != -1) 1754 { 1755 if(targetUniform->type == GL_SAMPLER_2D || 1756 targetUniform->type == GL_SAMPLER_CUBE) 1757 { 1758 for(int i = 0; i < count; i++) 1759 { 1760 unsigned int samplerIndex = targetUniform->vsRegisterIndex + i; 1761 1762 if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS) 1763 { 1764 ASSERT(samplersVS[samplerIndex].active); 1765 samplersVS[samplerIndex].logicalTextureUnit = v[i]; 1766 } 1767 } 1768 } 1769 else 1770 { 1771 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount()); 1772 } 1773 } 1774 1775 return true; 1776 } 1777 1778 bool Program::applyUniform2iv(GLint location, GLsizei count, const GLint *v) 1779 { 1780 float vector[MAX_UNIFORM_VECTORS][4]; 1781 1782 for(int i = 0; i < count; i++) 1783 { 1784 vector[i][0] = (float)v[0]; 1785 vector[i][1] = (float)v[1]; 1786 vector[i][2] = 0; 1787 vector[i][3] = 0; 1788 1789 v += 2; 1790 } 1791 1792 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1793 1794 if(targetUniform->psRegisterIndex != -1) 1795 { 1796 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount()); 1797 } 1798 1799 if(targetUniform->vsRegisterIndex != -1) 1800 { 1801 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount()); 1802 } 1803 1804 return true; 1805 } 1806 1807 bool Program::applyUniform3iv(GLint location, GLsizei count, const GLint *v) 1808 { 1809 float vector[MAX_UNIFORM_VECTORS][4]; 1810 1811 for(int i = 0; i < count; i++) 1812 { 1813 vector[i][0] = (float)v[0]; 1814 vector[i][1] = (float)v[1]; 1815 vector[i][2] = (float)v[2]; 1816 vector[i][3] = 0; 1817 1818 v += 3; 1819 } 1820 1821 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1822 1823 if(targetUniform->psRegisterIndex != -1) 1824 { 1825 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount()); 1826 } 1827 1828 if(targetUniform->vsRegisterIndex != -1) 1829 { 1830 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount()); 1831 } 1832 1833 return true; 1834 } 1835 1836 bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v) 1837 { 1838 float vector[MAX_UNIFORM_VECTORS][4]; 1839 1840 for(int i = 0; i < count; i++) 1841 { 1842 vector[i][0] = (float)v[0]; 1843 vector[i][1] = (float)v[1]; 1844 vector[i][2] = (float)v[2]; 1845 vector[i][3] = (float)v[3]; 1846 1847 v += 4; 1848 } 1849 1850 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1851 1852 if(targetUniform->psRegisterIndex != -1) 1853 { 1854 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount()); 1855 } 1856 1857 if(targetUniform->vsRegisterIndex != -1) 1858 { 1859 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount()); 1860 } 1861 1862 return true; 1863 } 1864 1865 void Program::appendToInfoLog(const char *format, ...) 1866 { 1867 if(!format) 1868 { 1869 return; 1870 } 1871 1872 char info[1024]; 1873 1874 va_list vararg; 1875 va_start(vararg, format); 1876 vsnprintf(info, sizeof(info), format, vararg); 1877 va_end(vararg); 1878 1879 size_t infoLength = strlen(info); 1880 1881 if(!infoLog) 1882 { 1883 infoLog = new char[infoLength + 2]; 1884 strcpy(infoLog, info); 1885 strcpy(infoLog + infoLength, "\n"); 1886 } 1887 else 1888 { 1889 size_t logLength = strlen(infoLog); 1890 char *newLog = new char[logLength + infoLength + 2]; 1891 strcpy(newLog, infoLog); 1892 strcpy(newLog + logLength, info); 1893 strcpy(newLog + logLength + infoLength, "\n"); 1894 1895 delete[] infoLog; 1896 infoLog = newLog; 1897 } 1898 } 1899 1900 void Program::resetInfoLog() 1901 { 1902 if(infoLog) 1903 { 1904 delete[] infoLog; 1905 infoLog = 0; 1906 } 1907 } 1908 1909 // Returns the program object to an unlinked state, before re-linking, or at destruction 1910 void Program::unlink() 1911 { 1912 delete vertexBinary; 1913 vertexBinary = 0; 1914 delete pixelBinary; 1915 pixelBinary = 0; 1916 1917 for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++) 1918 { 1919 linkedAttribute[index].name.clear(); 1920 attributeStream[index] = -1; 1921 } 1922 1923 for(int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++) 1924 { 1925 samplersPS[index].active = false; 1926 } 1927 1928 for(int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++) 1929 { 1930 samplersVS[index].active = false; 1931 } 1932 1933 while(!uniforms.empty()) 1934 { 1935 delete uniforms.back(); 1936 uniforms.pop_back(); 1937 } 1938 1939 uniformIndex.clear(); 1940 1941 delete[] infoLog; 1942 infoLog = 0; 1943 1944 linked = false; 1945 } 1946 1947 bool Program::isLinked() 1948 { 1949 return linked; 1950 } 1951 1952 bool Program::isValidated() const 1953 { 1954 return validated; 1955 } 1956 1957 void Program::release() 1958 { 1959 referenceCount--; 1960 1961 if(referenceCount == 0 && orphaned) 1962 { 1963 resourceManager->deleteProgram(handle); 1964 } 1965 } 1966 1967 void Program::addRef() 1968 { 1969 referenceCount++; 1970 } 1971 1972 unsigned int Program::getRefCount() const 1973 { 1974 return referenceCount; 1975 } 1976 1977 unsigned int Program::getSerial() const 1978 { 1979 return serial; 1980 } 1981 1982 unsigned int Program::issueSerial() 1983 { 1984 return currentSerial++; 1985 } 1986 1987 int Program::getInfoLogLength() const 1988 { 1989 if(!infoLog) 1990 { 1991 return 0; 1992 } 1993 else 1994 { 1995 return strlen(infoLog) + 1; 1996 } 1997 } 1998 1999 void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *buffer) 2000 { 2001 int index = 0; 2002 2003 if(bufSize > 0) 2004 { 2005 if(infoLog) 2006 { 2007 index = std::min(bufSize - 1, (int)strlen(infoLog)); 2008 memcpy(buffer, infoLog, index); 2009 } 2010 2011 buffer[index] = '\0'; 2012 } 2013 2014 if(length) 2015 { 2016 *length = index; 2017 } 2018 } 2019 2020 void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders) 2021 { 2022 int total = 0; 2023 2024 if(vertexShader) 2025 { 2026 if(total < maxCount) 2027 { 2028 shaders[total] = vertexShader->getName(); 2029 } 2030 2031 total++; 2032 } 2033 2034 if(fragmentShader) 2035 { 2036 if(total < maxCount) 2037 { 2038 shaders[total] = fragmentShader->getName(); 2039 } 2040 2041 total++; 2042 } 2043 2044 if(count) 2045 { 2046 *count = total; 2047 } 2048 } 2049 2050 void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const 2051 { 2052 // Skip over inactive attributes 2053 unsigned int activeAttribute = 0; 2054 unsigned int attribute; 2055 for(attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) 2056 { 2057 if(linkedAttribute[attribute].name.empty()) 2058 { 2059 continue; 2060 } 2061 2062 if(activeAttribute == index) 2063 { 2064 break; 2065 } 2066 2067 activeAttribute++; 2068 } 2069 2070 if(bufsize > 0) 2071 { 2072 const char *string = linkedAttribute[attribute].name.c_str(); 2073 2074 strncpy(name, string, bufsize); 2075 name[bufsize - 1] = '\0'; 2076 2077 if(length) 2078 { 2079 *length = strlen(name); 2080 } 2081 } 2082 2083 *size = 1; // Always a single 'type' instance 2084 2085 *type = linkedAttribute[attribute].type; 2086 } 2087 2088 size_t Program::getActiveAttributeCount() const 2089 { 2090 size_t count = 0; 2091 2092 for(size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; ++attributeIndex) 2093 { 2094 if(!linkedAttribute[attributeIndex].name.empty()) 2095 { 2096 count++; 2097 } 2098 } 2099 2100 return count; 2101 } 2102 2103 GLint Program::getActiveAttributeMaxLength() const 2104 { 2105 int maxLength = 0; 2106 2107 for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) 2108 { 2109 if(!linkedAttribute[attributeIndex].name.empty()) 2110 { 2111 maxLength = std::max((int)(linkedAttribute[attributeIndex].name.length() + 1), maxLength); 2112 } 2113 } 2114 2115 return maxLength; 2116 } 2117 2118 void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const 2119 { 2120 if(bufsize > 0) 2121 { 2122 std::string string = uniforms[index]->name; 2123 2124 if(uniforms[index]->isArray()) 2125 { 2126 string += "[0]"; 2127 } 2128 2129 strncpy(name, string.c_str(), bufsize); 2130 name[bufsize - 1] = '\0'; 2131 2132 if(length) 2133 { 2134 *length = strlen(name); 2135 } 2136 } 2137 2138 *size = uniforms[index]->size(); 2139 2140 *type = uniforms[index]->type; 2141 } 2142 2143 size_t Program::getActiveUniformCount() const 2144 { 2145 return uniforms.size(); 2146 } 2147 2148 GLint Program::getActiveUniformMaxLength() const 2149 { 2150 int maxLength = 0; 2151 2152 unsigned int numUniforms = uniforms.size(); 2153 for(unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++) 2154 { 2155 if(!uniforms[uniformIndex]->name.empty()) 2156 { 2157 int length = (int)(uniforms[uniformIndex]->name.length() + 1); 2158 if(uniforms[uniformIndex]->isArray()) 2159 { 2160 length += 3; // Counting in "[0]". 2161 } 2162 maxLength = std::max(length, maxLength); 2163 } 2164 } 2165 2166 return maxLength; 2167 } 2168 2169 void Program::flagForDeletion() 2170 { 2171 orphaned = true; 2172 } 2173 2174 bool Program::isFlaggedForDeletion() const 2175 { 2176 return orphaned; 2177 } 2178 2179 void Program::validate() 2180 { 2181 resetInfoLog(); 2182 2183 if(!isLinked()) 2184 { 2185 appendToInfoLog("Program has not been successfully linked."); 2186 validated = false; 2187 } 2188 else 2189 { 2190 applyUniforms(); 2191 if(!validateSamplers(true)) 2192 { 2193 validated = false; 2194 } 2195 else 2196 { 2197 validated = true; 2198 } 2199 } 2200 } 2201 2202 bool Program::validateSamplers(bool logErrors) 2203 { 2204 // if any two active samplers in a program are of different types, but refer to the same 2205 // texture image unit, and this is the current program, then ValidateProgram will fail, and 2206 // DrawArrays and DrawElements will issue the INVALID_OPERATION error. 2207 2208 TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; 2209 2210 for(unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; i++) 2211 { 2212 textureUnitType[i] = TEXTURE_UNKNOWN; 2213 } 2214 2215 for(unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) 2216 { 2217 if(samplersPS[i].active) 2218 { 2219 unsigned int unit = samplersPS[i].logicalTextureUnit; 2220 2221 if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS) 2222 { 2223 if(logErrors) 2224 { 2225 appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS); 2226 } 2227 2228 return false; 2229 } 2230 2231 if(textureUnitType[unit] != TEXTURE_UNKNOWN) 2232 { 2233 if(samplersPS[i].textureType != textureUnitType[unit]) 2234 { 2235 if(logErrors) 2236 { 2237 appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit); 2238 } 2239 2240 return false; 2241 } 2242 } 2243 else 2244 { 2245 textureUnitType[unit] = samplersPS[i].textureType; 2246 } 2247 } 2248 } 2249 2250 for(unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++) 2251 { 2252 if(samplersVS[i].active) 2253 { 2254 unsigned int unit = samplersVS[i].logicalTextureUnit; 2255 2256 if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS) 2257 { 2258 if(logErrors) 2259 { 2260 appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS); 2261 } 2262 2263 return false; 2264 } 2265 2266 if(textureUnitType[unit] != TEXTURE_UNKNOWN) 2267 { 2268 if(samplersVS[i].textureType != textureUnitType[unit]) 2269 { 2270 if(logErrors) 2271 { 2272 appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit); 2273 } 2274 2275 return false; 2276 } 2277 } 2278 else 2279 { 2280 textureUnitType[unit] = samplersVS[i].textureType; 2281 } 2282 } 2283 } 2284 2285 return true; 2286 } 2287 } 2288