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. [OpenGL ES 2.0.24] section 2.10.3 page 28. 17 18 #include "Program.h" 19 20 #include "main.h" 21 #include "Buffer.h" 22 #include "Shader.h" 23 #include "TransformFeedback.h" 24 #include "utilities.h" 25 #include "common/debug.h" 26 #include "Shader/PixelShader.hpp" 27 #include "Shader/VertexShader.hpp" 28 29 #include <algorithm> 30 #include <string> 31 #include <stdlib.h> 32 33 namespace es2 34 { 35 unsigned int Program::currentSerial = 1; 36 37 std::string str(int i) 38 { 39 char buffer[20]; 40 sprintf(buffer, "%d", i); 41 return buffer; 42 } 43 44 Uniform::BlockInfo::BlockInfo(const glsl::Uniform& uniform, int blockIndex) 45 { 46 if(blockIndex >= 0) 47 { 48 index = blockIndex; 49 offset = uniform.blockInfo.offset; 50 arrayStride = uniform.blockInfo.arrayStride; 51 matrixStride = uniform.blockInfo.matrixStride; 52 isRowMajorMatrix = uniform.blockInfo.isRowMajorMatrix; 53 } 54 else 55 { 56 index = -1; 57 offset = -1; 58 arrayStride = -1; 59 matrixStride = -1; 60 isRowMajorMatrix = false; 61 } 62 } 63 64 Uniform::Uniform(const glsl::Uniform &uniform, const BlockInfo &blockInfo) 65 : type(uniform.type), precision(uniform.precision), name(uniform.name), 66 arraySize(uniform.arraySize), blockInfo(blockInfo), fields(uniform.fields) 67 { 68 if((blockInfo.index == -1) && uniform.fields.empty()) 69 { 70 size_t bytes = UniformTypeSize(type) * size(); 71 data = new unsigned char[bytes]; 72 memset(data, 0, bytes); 73 } 74 else 75 { 76 data = nullptr; 77 } 78 dirty = true; 79 80 psRegisterIndex = -1; 81 vsRegisterIndex = -1; 82 } 83 84 Uniform::~Uniform() 85 { 86 delete[] data; 87 } 88 89 bool Uniform::isArray() const 90 { 91 return arraySize >= 1; 92 } 93 94 int Uniform::size() const 95 { 96 return arraySize > 0 ? arraySize : 1; 97 } 98 99 int Uniform::registerCount() const 100 { 101 return size() * VariableRegisterCount(type); 102 } 103 104 UniformBlock::UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize, std::vector<unsigned int> memberUniformIndexes) : 105 name(name), elementIndex(elementIndex), dataSize(dataSize), memberUniformIndexes(memberUniformIndexes), psRegisterIndex(GL_INVALID_INDEX), vsRegisterIndex(GL_INVALID_INDEX) 106 { 107 } 108 109 void UniformBlock::setRegisterIndex(GLenum shader, unsigned int registerIndex) 110 { 111 switch(shader) 112 { 113 case GL_VERTEX_SHADER: 114 vsRegisterIndex = registerIndex; 115 break; 116 case GL_FRAGMENT_SHADER: 117 psRegisterIndex = registerIndex; 118 break; 119 default: 120 UNREACHABLE(shader); 121 } 122 } 123 124 bool UniformBlock::isArrayElement() const 125 { 126 return elementIndex != GL_INVALID_INDEX; 127 } 128 129 bool UniformBlock::isReferencedByVertexShader() const 130 { 131 return vsRegisterIndex != GL_INVALID_INDEX; 132 } 133 134 bool UniformBlock::isReferencedByFragmentShader() const 135 { 136 return psRegisterIndex != GL_INVALID_INDEX; 137 } 138 139 UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) : name(name), element(element), index(index) 140 { 141 } 142 143 LinkedVarying::LinkedVarying() 144 { 145 } 146 147 LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, int reg, int col) 148 : name(name), type(type), size(size), reg(reg), col(col) 149 { 150 } 151 152 Program::Program(ResourceManager *manager, GLuint handle) : serial(issueSerial()), resourceManager(manager), handle(handle) 153 { 154 fragmentShader = 0; 155 vertexShader = 0; 156 pixelBinary = 0; 157 vertexBinary = 0; 158 159 transformFeedbackBufferMode = GL_INTERLEAVED_ATTRIBS; 160 totalLinkedVaryingsComponents = 0; 161 162 infoLog = 0; 163 validated = false; 164 165 resetUniformBlockBindings(); 166 unlink(); 167 168 orphaned = false; 169 retrievableBinary = false; 170 referenceCount = 0; 171 } 172 173 Program::~Program() 174 { 175 unlink(); 176 177 if(vertexShader) 178 { 179 vertexShader->release(); 180 } 181 182 if(fragmentShader) 183 { 184 fragmentShader->release(); 185 } 186 } 187 188 bool Program::attachShader(Shader *shader) 189 { 190 if(shader->getType() == GL_VERTEX_SHADER) 191 { 192 if(vertexShader) 193 { 194 return false; 195 } 196 197 vertexShader = (VertexShader*)shader; 198 vertexShader->addRef(); 199 } 200 else if(shader->getType() == GL_FRAGMENT_SHADER) 201 { 202 if(fragmentShader) 203 { 204 return false; 205 } 206 207 fragmentShader = (FragmentShader*)shader; 208 fragmentShader->addRef(); 209 } 210 else UNREACHABLE(shader->getType()); 211 212 return true; 213 } 214 215 bool Program::detachShader(Shader *shader) 216 { 217 if(shader->getType() == GL_VERTEX_SHADER) 218 { 219 if(vertexShader != shader) 220 { 221 return false; 222 } 223 224 vertexShader->release(); 225 vertexShader = 0; 226 } 227 else if(shader->getType() == GL_FRAGMENT_SHADER) 228 { 229 if(fragmentShader != shader) 230 { 231 return false; 232 } 233 234 fragmentShader->release(); 235 fragmentShader = 0; 236 } 237 else UNREACHABLE(shader->getType()); 238 239 return true; 240 } 241 242 int Program::getAttachedShadersCount() const 243 { 244 return (vertexShader ? 1 : 0) + (fragmentShader ? 1 : 0); 245 } 246 247 sw::PixelShader *Program::getPixelShader() 248 { 249 return pixelBinary; 250 } 251 252 sw::VertexShader *Program::getVertexShader() 253 { 254 return vertexBinary; 255 } 256 257 GLint Program::getFragDataLocation(const GLchar *name) 258 { 259 if(name && linked) 260 { 261 std::string baseName(name); 262 unsigned int subscript = GL_INVALID_INDEX; 263 baseName = ParseUniformName(baseName, &subscript); 264 for(auto const &varying : fragmentShader->varyings) 265 { 266 if(varying.qualifier == EvqFragmentOut) 267 { 268 if(varying.name == baseName) 269 { 270 ASSERT(varying.registerIndex >= 0); 271 272 if(subscript == GL_INVALID_INDEX) // No subscript 273 { 274 return varying.registerIndex; 275 } 276 277 int rowCount = VariableRowCount(varying.type); 278 int colCount = VariableColumnCount(varying.type); 279 280 return varying.registerIndex + (rowCount > 1 ? colCount * subscript : subscript); 281 } 282 } 283 } 284 } 285 286 return -1; 287 } 288 289 void Program::bindAttributeLocation(GLuint index, const char *name) 290 { 291 attributeBinding[name] = index; 292 } 293 294 GLint Program::getAttributeLocation(const char *name) 295 { 296 if(name) 297 { 298 std::string strName(name); 299 for(auto const &it : linkedAttribute) 300 { 301 if(it.name == strName) 302 { 303 return getAttributeBinding(it); 304 } 305 } 306 } 307 308 return -1; 309 } 310 311 int Program::getAttributeStream(int attributeIndex) 312 { 313 ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS); 314 315 return attributeStream[attributeIndex]; 316 } 317 318 // 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) 319 GLint Program::getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex) 320 { 321 GLint logicalTextureUnit = -1; 322 323 switch(type) 324 { 325 case sw::SAMPLER_PIXEL: 326 ASSERT(samplerIndex < sizeof(samplersPS) / sizeof(samplersPS[0])); 327 328 if(samplersPS[samplerIndex].active) 329 { 330 logicalTextureUnit = samplersPS[samplerIndex].logicalTextureUnit; 331 } 332 break; 333 case sw::SAMPLER_VERTEX: 334 ASSERT(samplerIndex < sizeof(samplersVS) / sizeof(samplersVS[0])); 335 336 if(samplersVS[samplerIndex].active) 337 { 338 logicalTextureUnit = samplersVS[samplerIndex].logicalTextureUnit; 339 } 340 break; 341 default: UNREACHABLE(type); 342 } 343 344 if(logicalTextureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS) 345 { 346 return logicalTextureUnit; 347 } 348 349 return -1; 350 } 351 352 // Returns the texture type for a given sampler type and index (0-15 for the pixel shader and 0-3 for the vertex shader) 353 TextureType Program::getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex) 354 { 355 switch(type) 356 { 357 case sw::SAMPLER_PIXEL: 358 ASSERT(samplerIndex < sizeof(samplersPS)/sizeof(samplersPS[0])); 359 ASSERT(samplersPS[samplerIndex].active); 360 return samplersPS[samplerIndex].textureType; 361 case sw::SAMPLER_VERTEX: 362 ASSERT(samplerIndex < sizeof(samplersVS)/sizeof(samplersVS[0])); 363 ASSERT(samplersVS[samplerIndex].active); 364 return samplersVS[samplerIndex].textureType; 365 default: UNREACHABLE(type); 366 } 367 368 return TEXTURE_2D; 369 } 370 371 bool Program::isUniformDefined(const std::string &name) const 372 { 373 unsigned int subscript = GL_INVALID_INDEX; 374 std::string baseName = es2::ParseUniformName(name, &subscript); 375 376 size_t numUniforms = uniformIndex.size(); 377 for(size_t location = 0; location < numUniforms; location++) 378 { 379 const unsigned int index = uniformIndex[location].index; 380 if((uniformIndex[location].name == baseName) && ((index == GL_INVALID_INDEX) || 381 ((uniforms[index]->isArray() && uniformIndex[location].element == subscript) || 382 (subscript == GL_INVALID_INDEX)))) 383 { 384 return true; 385 } 386 } 387 388 return false; 389 } 390 391 GLint Program::getUniformLocation(const std::string &name) const 392 { 393 unsigned int subscript = GL_INVALID_INDEX; 394 std::string baseName = es2::ParseUniformName(name, &subscript); 395 396 size_t numUniforms = uniformIndex.size(); 397 for(size_t location = 0; location < numUniforms; location++) 398 { 399 const unsigned int index = uniformIndex[location].index; 400 if((index != GL_INVALID_INDEX) && (uniformIndex[location].name == baseName) && 401 ((uniforms[index]->isArray() && uniformIndex[location].element == subscript) || 402 (subscript == GL_INVALID_INDEX))) 403 { 404 return (GLint)location; 405 } 406 } 407 408 return -1; 409 } 410 411 GLuint Program::getUniformIndex(const std::string &name) const 412 { 413 unsigned int subscript = GL_INVALID_INDEX; 414 std::string baseName = es2::ParseUniformName(name, &subscript); 415 416 // The app is not allowed to specify array indices other than 0 for arrays of basic types 417 if(subscript != 0 && subscript != GL_INVALID_INDEX) 418 { 419 return GL_INVALID_INDEX; 420 } 421 422 size_t numUniforms = uniforms.size(); 423 for(GLuint index = 0; index < numUniforms; index++) 424 { 425 if(uniforms[index]->name == baseName) 426 { 427 if(uniforms[index]->isArray() || subscript == GL_INVALID_INDEX) 428 { 429 return index; 430 } 431 } 432 } 433 434 return GL_INVALID_INDEX; 435 } 436 437 void Program::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const 438 { 439 ASSERT(uniformBlockIndex < getActiveUniformBlockCount()); 440 441 const UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex]; 442 443 switch(pname) 444 { 445 case GL_UNIFORM_BLOCK_DATA_SIZE: 446 *params = static_cast<GLint>(uniformBlock.dataSize); 447 break; 448 case GL_UNIFORM_BLOCK_NAME_LENGTH: 449 *params = static_cast<GLint>(uniformBlock.name.size() + 1 + (uniformBlock.isArrayElement() ? 3 : 0)); 450 break; 451 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: 452 *params = static_cast<GLint>(uniformBlock.memberUniformIndexes.size()); 453 break; 454 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: 455 { 456 for(unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++) 457 { 458 params[blockMemberIndex] = static_cast<GLint>(uniformBlock.memberUniformIndexes[blockMemberIndex]); 459 } 460 } 461 break; 462 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: 463 *params = static_cast<GLint>(uniformBlock.isReferencedByVertexShader()); 464 break; 465 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: 466 *params = static_cast<GLint>(uniformBlock.isReferencedByFragmentShader()); 467 break; 468 default: UNREACHABLE(pname); 469 } 470 } 471 472 GLuint Program::getUniformBlockIndex(const std::string &name) const 473 { 474 unsigned int subscript = GL_INVALID_INDEX; 475 std::string baseName = es2::ParseUniformName(name, &subscript); 476 477 size_t numUniformBlocks = getActiveUniformBlockCount(); 478 for(GLuint blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++) 479 { 480 const UniformBlock &uniformBlock = *uniformBlocks[blockIndex]; 481 if(uniformBlock.name == baseName) 482 { 483 const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0); 484 if(subscript == uniformBlock.elementIndex || arrayElementZero) 485 { 486 return blockIndex; 487 } 488 } 489 } 490 491 return GL_INVALID_INDEX; 492 } 493 494 void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding) 495 { 496 if(uniformBlockIndex >= getActiveUniformBlockCount()) 497 { 498 return error(GL_INVALID_VALUE); 499 } 500 501 uniformBlockBindings[uniformBlockIndex] = uniformBlockBinding; 502 } 503 504 GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const 505 { 506 if(uniformBlockIndex >= getActiveUniformBlockCount()) 507 { 508 return error(GL_INVALID_VALUE, GL_INVALID_INDEX); 509 } 510 return uniformBlockBindings[uniformBlockIndex]; 511 } 512 513 void Program::resetUniformBlockBindings() 514 { 515 for(unsigned int blockId = 0; blockId < MAX_UNIFORM_BUFFER_BINDINGS; blockId++) 516 { 517 uniformBlockBindings[blockId] = 0; 518 } 519 } 520 521 bool Program::setUniformfv(GLint location, GLsizei count, const GLfloat *v, int numElements) 522 { 523 ASSERT(numElements >= 1 && numElements <= 4); 524 525 static GLenum floatType[] = { GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 }; 526 static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 }; 527 528 if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX)) 529 { 530 return false; 531 } 532 533 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 534 targetUniform->dirty = true; 535 536 int size = targetUniform->size(); 537 538 if(size == 1 && count > 1) 539 { 540 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 541 } 542 543 count = std::min(size - (int)uniformIndex[location].element, count); 544 545 int index = numElements - 1; 546 if(targetUniform->type == floatType[index]) 547 { 548 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat)* numElements, 549 v, numElements * sizeof(GLfloat) * count); 550 } 551 else if(targetUniform->type == boolType[index]) 552 { 553 GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * numElements; 554 555 for(int i = 0; i < count * numElements; i++) 556 { 557 boolParams[i] = (v[i] == 0.0f) ? GL_FALSE : GL_TRUE; 558 } 559 } 560 else 561 { 562 return false; 563 } 564 565 return true; 566 } 567 568 bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) 569 { 570 return setUniformfv(location, count, v, 1); 571 } 572 573 bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) 574 { 575 return setUniformfv(location, count, v, 2); 576 } 577 578 bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) 579 { 580 return setUniformfv(location, count, v, 3); 581 } 582 583 bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) 584 { 585 return setUniformfv(location, count, v, 4); 586 } 587 588 bool Program::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum type) 589 { 590 int numElements; 591 switch(type) 592 { 593 case GL_FLOAT_MAT2: 594 numElements = 4; 595 break; 596 case GL_FLOAT_MAT2x3: 597 case GL_FLOAT_MAT3x2: 598 numElements = 6; 599 break; 600 case GL_FLOAT_MAT2x4: 601 case GL_FLOAT_MAT4x2: 602 numElements = 8; 603 break; 604 case GL_FLOAT_MAT3: 605 numElements = 9; 606 break; 607 case GL_FLOAT_MAT3x4: 608 case GL_FLOAT_MAT4x3: 609 numElements = 12; 610 break; 611 case GL_FLOAT_MAT4: 612 numElements = 16; 613 break; 614 default: 615 return false; 616 } 617 618 if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX)) 619 { 620 return false; 621 } 622 623 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 624 targetUniform->dirty = true; 625 626 if(targetUniform->type != type) 627 { 628 return false; 629 } 630 631 int size = targetUniform->size(); 632 633 if(size == 1 && count > 1) 634 { 635 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 636 } 637 638 count = std::min(size - (int)uniformIndex[location].element, count); 639 640 GLfloat* dst = reinterpret_cast<GLfloat*>(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * numElements); 641 642 if(transpose == GL_FALSE) 643 { 644 memcpy(dst, value, numElements * sizeof(GLfloat) * count); 645 } 646 else 647 { 648 const int rowSize = VariableRowCount(type); 649 const int colSize = VariableColumnCount(type); 650 for(int n = 0; n < count; ++n) 651 { 652 for(int i = 0; i < colSize; ++i) 653 { 654 for(int j = 0; j < rowSize; ++j) 655 { 656 dst[i * rowSize + j] = value[j * colSize + i]; 657 } 658 } 659 dst += numElements; 660 value += numElements; 661 } 662 } 663 664 665 return true; 666 } 667 668 bool Program::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 669 { 670 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2); 671 } 672 673 bool Program::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 674 { 675 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2x3); 676 } 677 678 bool Program::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 679 { 680 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2x4); 681 } 682 683 bool Program::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 684 { 685 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3); 686 } 687 688 bool Program::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 689 { 690 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3x2); 691 } 692 693 bool Program::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 694 { 695 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3x4); 696 } 697 698 bool Program::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 699 { 700 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4); 701 } 702 703 bool Program::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 704 { 705 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4x2); 706 } 707 708 bool Program::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 709 { 710 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4x3); 711 } 712 713 bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v) 714 { 715 if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX)) 716 { 717 return false; 718 } 719 720 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 721 targetUniform->dirty = true; 722 723 int size = targetUniform->size(); 724 725 if(size == 1 && count > 1) 726 { 727 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 728 } 729 730 count = std::min(size - (int)uniformIndex[location].element, count); 731 732 if(targetUniform->type == GL_INT || IsSamplerUniform(targetUniform->type)) 733 { 734 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint), 735 v, sizeof(GLint) * count); 736 } 737 else if(targetUniform->type == GL_BOOL) 738 { 739 GLboolean *boolParams = new GLboolean[count]; 740 741 for(int i = 0; i < count; i++) 742 { 743 if(v[i] == 0) 744 { 745 boolParams[i] = GL_FALSE; 746 } 747 else 748 { 749 boolParams[i] = GL_TRUE; 750 } 751 } 752 753 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean), 754 boolParams, sizeof(GLboolean) * count); 755 756 delete[] boolParams; 757 } 758 else 759 { 760 return false; 761 } 762 763 return true; 764 } 765 766 bool Program::setUniformiv(GLint location, GLsizei count, const GLint *v, int numElements) 767 { 768 static GLenum intType[] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 }; 769 static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 }; 770 771 if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX)) 772 { 773 return false; 774 } 775 776 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 777 targetUniform->dirty = true; 778 779 int size = targetUniform->size(); 780 781 if(size == 1 && count > 1) 782 { 783 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 784 } 785 786 count = std::min(size - (int)uniformIndex[location].element, count); 787 788 int index = numElements - 1; 789 if(targetUniform->type == intType[index]) 790 { 791 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint)* numElements, 792 v, numElements * sizeof(GLint)* count); 793 } 794 else if(targetUniform->type == boolType[index]) 795 { 796 GLboolean *boolParams = new GLboolean[count * numElements]; 797 798 for(int i = 0; i < count * numElements; i++) 799 { 800 boolParams[i] = (v[i] == 0) ? GL_FALSE : GL_TRUE; 801 } 802 803 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean)* numElements, 804 boolParams, numElements * sizeof(GLboolean)* count); 805 806 delete[] boolParams; 807 } 808 else 809 { 810 return false; 811 } 812 813 return true; 814 } 815 816 bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v) 817 { 818 return setUniformiv(location, count, v, 2); 819 } 820 821 bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v) 822 { 823 return setUniformiv(location, count, v, 3); 824 } 825 826 bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v) 827 { 828 return setUniformiv(location, count, v, 4); 829 } 830 831 bool Program::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) 832 { 833 if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX)) 834 { 835 return false; 836 } 837 838 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 839 targetUniform->dirty = true; 840 841 int size = targetUniform->size(); 842 843 if(size == 1 && count > 1) 844 { 845 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 846 } 847 848 count = std::min(size - (int)uniformIndex[location].element, count); 849 850 if(targetUniform->type == GL_UNSIGNED_INT) 851 { 852 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint), 853 v, sizeof(GLuint)* count); 854 } 855 else if(targetUniform->type == GL_BOOL) 856 { 857 GLboolean *boolParams = new GLboolean[count]; 858 859 for(int i = 0; i < count; i++) 860 { 861 if(v[i] == 0) 862 { 863 boolParams[i] = GL_FALSE; 864 } 865 else 866 { 867 boolParams[i] = GL_TRUE; 868 } 869 } 870 871 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean), 872 boolParams, sizeof(GLboolean)* count); 873 874 delete[] boolParams; 875 } 876 else 877 { 878 return false; 879 } 880 881 return true; 882 } 883 884 bool Program::setUniformuiv(GLint location, GLsizei count, const GLuint *v, int numElements) 885 { 886 static GLenum uintType[] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4 }; 887 static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 }; 888 889 if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX)) 890 { 891 return false; 892 } 893 894 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 895 targetUniform->dirty = true; 896 897 int size = targetUniform->size(); 898 899 if(size == 1 && count > 1) 900 { 901 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION 902 } 903 904 count = std::min(size - (int)uniformIndex[location].element, count); 905 906 int index = numElements - 1; 907 if(targetUniform->type == uintType[index]) 908 { 909 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint)* numElements, 910 v, numElements * sizeof(GLuint)* count); 911 } 912 else if(targetUniform->type == boolType[index]) 913 { 914 GLboolean *boolParams = new GLboolean[count * numElements]; 915 916 for(int i = 0; i < count * numElements; i++) 917 { 918 boolParams[i] = (v[i] == 0) ? GL_FALSE : GL_TRUE; 919 } 920 921 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean)* numElements, 922 boolParams, numElements * sizeof(GLboolean)* count); 923 924 delete[] boolParams; 925 } 926 else 927 { 928 return false; 929 } 930 931 return true; 932 } 933 934 bool Program::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) 935 { 936 return setUniformuiv(location, count, v, 2); 937 } 938 939 bool Program::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) 940 { 941 return setUniformuiv(location, count, v, 3); 942 } 943 944 bool Program::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) 945 { 946 return setUniformuiv(location, count, v, 4); 947 } 948 949 bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params) 950 { 951 if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX)) 952 { 953 return false; 954 } 955 956 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 957 unsigned int count = UniformComponentCount(targetUniform->type); 958 959 // Sized query - ensure the provided buffer is large enough 960 if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLfloat)) 961 { 962 return false; 963 } 964 965 switch(UniformComponentType(targetUniform->type)) 966 { 967 case GL_BOOL: 968 { 969 GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * count; 970 971 for(unsigned int i = 0; i < count; i++) 972 { 973 params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f; 974 } 975 } 976 break; 977 case GL_FLOAT: 978 memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLfloat), 979 count * sizeof(GLfloat)); 980 break; 981 case GL_INT: 982 { 983 GLint *intParams = (GLint*)targetUniform->data + uniformIndex[location].element * count; 984 985 for(unsigned int i = 0; i < count; i++) 986 { 987 params[i] = (float)intParams[i]; 988 } 989 } 990 break; 991 case GL_UNSIGNED_INT: 992 { 993 GLuint *uintParams = (GLuint*)targetUniform->data + uniformIndex[location].element * count; 994 995 for(unsigned int i = 0; i < count; i++) 996 { 997 params[i] = (float)uintParams[i]; 998 } 999 } 1000 break; 1001 default: UNREACHABLE(targetUniform->type); 1002 } 1003 1004 return true; 1005 } 1006 1007 bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params) 1008 { 1009 if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX)) 1010 { 1011 return false; 1012 } 1013 1014 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1015 unsigned int count = UniformComponentCount(targetUniform->type); 1016 1017 // Sized query - ensure the provided buffer is large enough 1018 if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLint)) 1019 { 1020 return false; 1021 } 1022 1023 switch(UniformComponentType(targetUniform->type)) 1024 { 1025 case GL_BOOL: 1026 { 1027 GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count; 1028 1029 for(unsigned int i = 0; i < count; i++) 1030 { 1031 params[i] = (GLint)boolParams[i]; 1032 } 1033 } 1034 break; 1035 case GL_FLOAT: 1036 { 1037 GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count; 1038 1039 for(unsigned int i = 0; i < count; i++) 1040 { 1041 params[i] = (GLint)floatParams[i]; 1042 } 1043 } 1044 break; 1045 case GL_INT: 1046 case GL_UNSIGNED_INT: 1047 memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLint), 1048 count * sizeof(GLint)); 1049 break; 1050 default: UNREACHABLE(targetUniform->type); 1051 } 1052 1053 return true; 1054 } 1055 1056 bool Program::getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params) 1057 { 1058 if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX)) 1059 { 1060 return false; 1061 } 1062 1063 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1064 unsigned int count = UniformComponentCount(targetUniform->type); 1065 1066 // Sized query - ensure the provided buffer is large enough 1067 if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLuint)) 1068 { 1069 return false; 1070 } 1071 1072 switch(UniformComponentType(targetUniform->type)) 1073 { 1074 case GL_BOOL: 1075 { 1076 GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count; 1077 1078 for(unsigned int i = 0; i < count; i++) 1079 { 1080 params[i] = (GLuint)boolParams[i]; 1081 } 1082 } 1083 break; 1084 case GL_FLOAT: 1085 { 1086 GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count; 1087 1088 for(unsigned int i = 0; i < count; i++) 1089 { 1090 params[i] = (GLuint)floatParams[i]; 1091 } 1092 } 1093 break; 1094 case GL_INT: 1095 case GL_UNSIGNED_INT: 1096 memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLuint), 1097 count * sizeof(GLuint)); 1098 break; 1099 default: UNREACHABLE(targetUniform->type); 1100 } 1101 1102 return true; 1103 } 1104 1105 void Program::dirtyAllUniforms() 1106 { 1107 size_t numUniforms = uniforms.size(); 1108 for(size_t index = 0; index < numUniforms; index++) 1109 { 1110 uniforms[index]->dirty = true; 1111 } 1112 } 1113 1114 // Applies all the uniforms set for this program object to the device 1115 void Program::applyUniforms(Device *device) 1116 { 1117 GLint numUniforms = static_cast<GLint>(uniformIndex.size()); 1118 for(GLint location = 0; location < numUniforms; location++) 1119 { 1120 if((uniformIndex[location].element != 0) || (uniformIndex[location].index == GL_INVALID_INDEX)) 1121 { 1122 continue; 1123 } 1124 1125 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 1126 1127 if(targetUniform->dirty && (targetUniform->blockInfo.index == -1)) 1128 { 1129 GLsizei size = targetUniform->size(); 1130 GLfloat *f = (GLfloat*)targetUniform->data; 1131 GLint *i = (GLint*)targetUniform->data; 1132 GLuint *ui = (GLuint*)targetUniform->data; 1133 GLboolean *b = (GLboolean*)targetUniform->data; 1134 1135 switch(targetUniform->type) 1136 { 1137 case GL_BOOL: applyUniform1bv(device, location, size, b); break; 1138 case GL_BOOL_VEC2: applyUniform2bv(device, location, size, b); break; 1139 case GL_BOOL_VEC3: applyUniform3bv(device, location, size, b); break; 1140 case GL_BOOL_VEC4: applyUniform4bv(device, location, size, b); break; 1141 case GL_FLOAT: applyUniform1fv(device, location, size, f); break; 1142 case GL_FLOAT_VEC2: applyUniform2fv(device, location, size, f); break; 1143 case GL_FLOAT_VEC3: applyUniform3fv(device, location, size, f); break; 1144 case GL_FLOAT_VEC4: applyUniform4fv(device, location, size, f); break; 1145 case GL_FLOAT_MAT2: applyUniformMatrix2fv(device, location, size, f); break; 1146 case GL_FLOAT_MAT2x3: applyUniformMatrix2x3fv(device, location, size, f); break; 1147 case GL_FLOAT_MAT2x4: applyUniformMatrix2x4fv(device, location, size, f); break; 1148 case GL_FLOAT_MAT3x2: applyUniformMatrix3x2fv(device, location, size, f); break; 1149 case GL_FLOAT_MAT3: applyUniformMatrix3fv(device, location, size, f); break; 1150 case GL_FLOAT_MAT3x4: applyUniformMatrix3x4fv(device, location, size, f); break; 1151 case GL_FLOAT_MAT4x2: applyUniformMatrix4x2fv(device, location, size, f); break; 1152 case GL_FLOAT_MAT4x3: applyUniformMatrix4x3fv(device, location, size, f); break; 1153 case GL_FLOAT_MAT4: applyUniformMatrix4fv(device, location, size, f); break; 1154 case GL_SAMPLER_2D: 1155 case GL_SAMPLER_CUBE: 1156 case GL_SAMPLER_2D_RECT_ARB: 1157 case GL_SAMPLER_EXTERNAL_OES: 1158 case GL_SAMPLER_3D_OES: 1159 case GL_SAMPLER_2D_ARRAY: 1160 case GL_SAMPLER_2D_SHADOW: 1161 case GL_SAMPLER_CUBE_SHADOW: 1162 case GL_SAMPLER_2D_ARRAY_SHADOW: 1163 case GL_INT_SAMPLER_2D: 1164 case GL_UNSIGNED_INT_SAMPLER_2D: 1165 case GL_INT_SAMPLER_CUBE: 1166 case GL_UNSIGNED_INT_SAMPLER_CUBE: 1167 case GL_INT_SAMPLER_3D: 1168 case GL_UNSIGNED_INT_SAMPLER_3D: 1169 case GL_INT_SAMPLER_2D_ARRAY: 1170 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 1171 case GL_INT: applyUniform1iv(device, location, size, i); break; 1172 case GL_INT_VEC2: applyUniform2iv(device, location, size, i); break; 1173 case GL_INT_VEC3: applyUniform3iv(device, location, size, i); break; 1174 case GL_INT_VEC4: applyUniform4iv(device, location, size, i); break; 1175 case GL_UNSIGNED_INT: applyUniform1uiv(device, location, size, ui); break; 1176 case GL_UNSIGNED_INT_VEC2: applyUniform2uiv(device, location, size, ui); break; 1177 case GL_UNSIGNED_INT_VEC3: applyUniform3uiv(device, location, size, ui); break; 1178 case GL_UNSIGNED_INT_VEC4: applyUniform4uiv(device, location, size, ui); break; 1179 default: 1180 UNREACHABLE(targetUniform->type); 1181 } 1182 1183 targetUniform->dirty = false; 1184 } 1185 } 1186 } 1187 1188 void Program::applyUniformBuffers(Device *device, BufferBinding* uniformBuffers) 1189 { 1190 GLint vertexUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS]; 1191 GLint fragmentUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS]; 1192 1193 for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++) 1194 { 1195 vertexUniformBuffers[bufferBindingIndex] = -1; 1196 } 1197 1198 for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++) 1199 { 1200 fragmentUniformBuffers[bufferBindingIndex] = -1; 1201 } 1202 1203 int vertexUniformBufferIndex = 0; 1204 int fragmentUniformBufferIndex = 0; 1205 for(unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlocks.size(); uniformBlockIndex++) 1206 { 1207 UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex]; 1208 1209 // Unnecessary to apply an unreferenced standard or shared UBO 1210 if(!uniformBlock.isReferencedByVertexShader() && !uniformBlock.isReferencedByFragmentShader()) 1211 { 1212 continue; 1213 } 1214 1215 GLuint blockBinding = uniformBlockBindings[uniformBlockIndex]; 1216 1217 if(uniformBlock.isReferencedByVertexShader()) 1218 { 1219 vertexUniformBuffers[vertexUniformBufferIndex++] = blockBinding; 1220 } 1221 1222 if(uniformBlock.isReferencedByFragmentShader()) 1223 { 1224 fragmentUniformBuffers[fragmentUniformBufferIndex++] = blockBinding; 1225 } 1226 } 1227 1228 for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++) 1229 { 1230 int index = vertexUniformBuffers[bufferBindingIndex]; 1231 Buffer* vsBuffer = (index != -1) ? (Buffer*)uniformBuffers[index].get() : nullptr; 1232 device->VertexProcessor::setUniformBuffer(bufferBindingIndex, 1233 vsBuffer ? vsBuffer->getResource() : nullptr, (index != -1) ? uniformBuffers[index].getOffset() : 0); 1234 index = fragmentUniformBuffers[bufferBindingIndex]; 1235 Buffer* psBuffer = (index != -1) ? (Buffer*)uniformBuffers[index].get() : nullptr; 1236 device->PixelProcessor::setUniformBuffer(bufferBindingIndex, 1237 psBuffer ? psBuffer->getResource() : nullptr, (index != -1) ? uniformBuffers[index].getOffset() : 0); 1238 } 1239 } 1240 1241 void Program::applyTransformFeedback(Device *device, TransformFeedback* transformFeedback) 1242 { 1243 // Make sure the flags will fit in a 64 bit unsigned int variable 1244 ASSERT(sw::max<int>(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS) <= 64); 1245 1246 BufferBinding* transformFeedbackBuffers = (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused()) ? transformFeedback->getBuffers() : nullptr; 1247 1248 uint64_t enableTransformFeedback = 0; 1249 if(!transformFeedbackBuffers) 1250 { 1251 for(unsigned int index = 0; index < sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++index) 1252 { 1253 device->VertexProcessor::setTransformFeedbackBuffer(index, nullptr, 0, 0, 0, 0, 0); 1254 } 1255 device->VertexProcessor::enableTransformFeedback(enableTransformFeedback); 1256 return; 1257 } 1258 1259 unsigned int maxVaryings = static_cast<unsigned int>(transformFeedbackLinkedVaryings.size()); 1260 switch(transformFeedbackBufferMode) 1261 { 1262 case GL_SEPARATE_ATTRIBS: 1263 { 1264 maxVaryings = sw::min(maxVaryings, (unsigned int)MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS); 1265 // Attribs go to separate buffers 1266 for(unsigned int index = 0; index < maxVaryings; ++index) 1267 { 1268 int size = transformFeedbackLinkedVaryings[index].size; 1269 int rowCount = VariableRowCount(transformFeedbackLinkedVaryings[index].type); 1270 int colCount = VariableColumnCount(transformFeedbackLinkedVaryings[index].type); 1271 int nbRegs = rowCount > 1 ? colCount * size : size; 1272 int nbComponentsPerReg = rowCount > 1 ? rowCount : colCount; 1273 int componentStride = rowCount * colCount * size; 1274 int baseOffset = transformFeedback->vertexOffset() * componentStride * sizeof(float); 1275 device->VertexProcessor::setTransformFeedbackBuffer(index, 1276 transformFeedbackBuffers[index].get()->getResource(), 1277 transformFeedbackBuffers[index].getOffset() + baseOffset, 1278 transformFeedbackLinkedVaryings[index].reg * 4 + transformFeedbackLinkedVaryings[index].col, 1279 nbRegs, nbComponentsPerReg, componentStride); 1280 enableTransformFeedback |= 1ULL << index; 1281 } 1282 } 1283 break; 1284 case GL_INTERLEAVED_ATTRIBS: 1285 { 1286 // OpenGL ES 3.0.4 spec, section 2.15.2: 1287 // In INTERLEAVED_ATTRIBS mode, the values of one or more output variables 1288 // written by a vertex shader are written, interleaved, into the buffer object 1289 // bound to the first transform feedback binding point (index = 0). 1290 sw::Resource* resource = transformFeedbackBuffers[0].get()->getResource(); 1291 int componentStride = static_cast<int>(totalLinkedVaryingsComponents); 1292 int baseOffset = transformFeedbackBuffers[0].getOffset() + (transformFeedback->vertexOffset() * componentStride * sizeof(float)); 1293 maxVaryings = sw::min(maxVaryings, (unsigned int)sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS); 1294 int totalComponents = 0; 1295 for(unsigned int index = 0; index < maxVaryings; ++index) 1296 { 1297 int size = transformFeedbackLinkedVaryings[index].size; 1298 int rowCount = VariableRowCount(transformFeedbackLinkedVaryings[index].type); 1299 int colCount = VariableColumnCount(transformFeedbackLinkedVaryings[index].type); 1300 int nbRegs = rowCount > 1 ? colCount * size : size; 1301 int nbComponentsPerReg = rowCount > 1 ? rowCount : colCount; 1302 device->VertexProcessor::setTransformFeedbackBuffer(index, resource, 1303 baseOffset + (totalComponents * sizeof(float)), 1304 transformFeedbackLinkedVaryings[index].reg * 4 + transformFeedbackLinkedVaryings[index].col, 1305 nbRegs, nbComponentsPerReg, componentStride); 1306 totalComponents += rowCount * colCount * size; 1307 enableTransformFeedback |= 1ULL << index; 1308 } 1309 } 1310 break; 1311 default: 1312 UNREACHABLE(transformFeedbackBufferMode); 1313 break; 1314 } 1315 1316 // Unset all other transform feedback buffers 1317 for(unsigned int index = maxVaryings; index < sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++index) 1318 { 1319 device->VertexProcessor::setTransformFeedbackBuffer(index, nullptr, 0, 0, 0, 0, 0); 1320 } 1321 1322 device->VertexProcessor::enableTransformFeedback(enableTransformFeedback); 1323 } 1324 1325 bool Program::linkVaryings() 1326 { 1327 glsl::VaryingList &psVaryings = fragmentShader->varyings; 1328 glsl::VaryingList &vsVaryings = vertexShader->varyings; 1329 1330 for(auto const &input : psVaryings) 1331 { 1332 bool matched = false; 1333 1334 for(auto const &output : vsVaryings) 1335 { 1336 if(output.name == input.name) 1337 { 1338 if(output.type != input.type || output.size() != input.size()) 1339 { 1340 appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output.name.c_str()); 1341 1342 return false; 1343 } 1344 1345 if((output.qualifier == EvqFlatOut) ^ (input.qualifier == EvqFlatIn)) 1346 { 1347 appendToInfoLog("Interpolation qualifiers for %s differ between vertex and fragment shaders", output.name.c_str()); 1348 1349 return false; 1350 } 1351 1352 if(!areMatchingFields(input.fields, output.fields, input.name)) 1353 { 1354 return false; 1355 } 1356 1357 matched = true; 1358 break; 1359 } 1360 } 1361 1362 if(!matched) 1363 { 1364 // If a fragment varying is declared but not statically used, it's not an error to not have a matching vertex varying. 1365 if(input.registerIndex >= 0) 1366 { 1367 appendToInfoLog("Fragment varying %s does not match any vertex varying", input.name.c_str()); 1368 1369 return false; 1370 } 1371 } 1372 } 1373 1374 for(auto const &output : vsVaryings) 1375 { 1376 bool matched = false; 1377 1378 for(auto const &input : psVaryings) 1379 { 1380 if(output.name == input.name) 1381 { 1382 int in = input.registerIndex; 1383 int out = output.registerIndex; 1384 int components = VariableRegisterSize(output.type); 1385 int registers = VariableRegisterCount(output.type) * output.size(); 1386 1387 if(in < 0) // Fragment varying declared but not used 1388 { 1389 continue; 1390 } 1391 1392 if(in + registers >= MAX_VARYING_VECTORS) 1393 { 1394 appendToInfoLog("Too many varyings"); 1395 return false; 1396 } 1397 1398 if(out >= 0) 1399 { 1400 if(out + registers >= MAX_VARYING_VECTORS) 1401 { 1402 appendToInfoLog("Too many varyings"); 1403 return false; 1404 } 1405 1406 for(int i = 0; i < registers; i++) 1407 { 1408 vertexBinary->setOutput(out + i, components, sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, pixelBinary->getInput(in + i, 0).flat)); 1409 } 1410 } 1411 else // Vertex varying is declared but not written to 1412 { 1413 for(int i = 0; i < registers; i++) 1414 { 1415 pixelBinary->setInput(in + i, components, sw::Shader::Semantic()); 1416 } 1417 } 1418 1419 matched = true; 1420 break; 1421 } 1422 } 1423 1424 if(!matched) 1425 { 1426 // For openGL ES 3.0, we need to still add the vertex shader outputs for unmatched varyings, for transform feedback. 1427 for(const std::string &indexedTfVaryingName : transformFeedbackVaryings) 1428 { 1429 std::string tfVaryingName = es2::ParseUniformName(indexedTfVaryingName, nullptr); 1430 1431 if(tfVaryingName == output.name) 1432 { 1433 int out = output.registerIndex; 1434 int components = VariableRegisterSize(output.type); 1435 int registers = VariableRegisterCount(output.type) * output.size(); 1436 1437 if(out >= 0) 1438 { 1439 if(out + registers >= MAX_VARYING_VECTORS) 1440 { 1441 appendToInfoLog("Too many varyings"); 1442 return false; 1443 } 1444 1445 for(int i = 0; i < registers; i++) 1446 { 1447 vertexBinary->setOutput(out + i, components, sw::Shader::Semantic(sw::Shader::USAGE_COLOR)); 1448 } 1449 } 1450 break; 1451 } 1452 } 1453 } 1454 } 1455 1456 return true; 1457 } 1458 1459 bool Program::linkTransformFeedback() 1460 { 1461 size_t totalComponents = 0; 1462 totalLinkedVaryingsComponents = 0; 1463 1464 std::set<std::string> uniqueNames; 1465 1466 for(const std::string &indexedTfVaryingName : transformFeedbackVaryings) 1467 { 1468 unsigned int subscript = GL_INVALID_INDEX; 1469 std::string tfVaryingName = es2::ParseUniformName(indexedTfVaryingName, &subscript); 1470 bool hasSubscript = (subscript != GL_INVALID_INDEX); 1471 1472 if(tfVaryingName.find('[') != std::string::npos) 1473 { 1474 appendToInfoLog("Capture of array sub-elements is undefined and not supported."); 1475 return false; 1476 } 1477 1478 bool found = false; 1479 for(const glsl::Varying varying : vertexShader->varyings) 1480 { 1481 if(tfVaryingName == varying.name) 1482 { 1483 if(uniqueNames.count(indexedTfVaryingName) > 0) 1484 { 1485 appendToInfoLog("Two transform feedback varyings specify the same output variable (%s)", indexedTfVaryingName.c_str()); 1486 return false; 1487 } 1488 uniqueNames.insert(indexedTfVaryingName); 1489 1490 if(hasSubscript && ((static_cast<int>(subscript)) >= varying.size())) 1491 { 1492 appendToInfoLog("Specified transform feedback varying index out of bounds (%s)", indexedTfVaryingName.c_str()); 1493 return false; 1494 } 1495 1496 int size = hasSubscript ? 1 : varying.size(); 1497 1498 int rowCount = VariableRowCount(varying.type); 1499 int colCount = VariableColumnCount(varying.type); 1500 int componentCount = rowCount * colCount * size; 1501 if(transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS && 1502 componentCount > sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS) 1503 { 1504 appendToInfoLog("Transform feedback varying's %s components (%d) exceed the maximum separate components (%d).", 1505 varying.name.c_str(), componentCount, sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS); 1506 return false; 1507 } 1508 1509 totalComponents += componentCount; 1510 1511 int reg = varying.registerIndex; 1512 if(hasSubscript) 1513 { 1514 reg += rowCount > 1 ? colCount * subscript : subscript; 1515 } 1516 int col = varying.column; 1517 if(tfVaryingName == "gl_PointSize") 1518 { 1519 // Point size is stored in the y element of the vector, not the x element 1520 col = 1; // FIXME: varying.col could already contain this information 1521 } 1522 transformFeedbackLinkedVaryings.push_back(LinkedVarying(varying.name, varying.type, size, reg, col)); 1523 1524 found = true; 1525 break; 1526 } 1527 } 1528 1529 if(!found) 1530 { 1531 appendToInfoLog("Transform feedback varying %s does not exist in the vertex shader.", tfVaryingName.c_str()); 1532 return false; 1533 } 1534 } 1535 1536 if(transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && 1537 totalComponents > sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS) 1538 { 1539 appendToInfoLog("Transform feedback varying total components (%d) exceed the maximum separate components (%d).", 1540 totalComponents, sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS); 1541 return false; 1542 } 1543 1544 totalLinkedVaryingsComponents = totalComponents; 1545 1546 return true; 1547 } 1548 1549 // Links the code of the vertex and pixel shader by matching up their varyings, 1550 // compiling them into binaries, determining the attribute mappings, and collecting 1551 // a list of uniforms 1552 void Program::link() 1553 { 1554 unlink(); 1555 1556 resetUniformBlockBindings(); 1557 1558 if(!fragmentShader || !fragmentShader->isCompiled()) 1559 { 1560 return; 1561 } 1562 1563 if(!vertexShader || !vertexShader->isCompiled()) 1564 { 1565 return; 1566 } 1567 1568 vertexBinary = new sw::VertexShader(vertexShader->getVertexShader()); 1569 pixelBinary = new sw::PixelShader(fragmentShader->getPixelShader()); 1570 1571 if(!linkVaryings()) 1572 { 1573 return; 1574 } 1575 1576 if(!linkAttributes()) 1577 { 1578 return; 1579 } 1580 1581 // Link uniform blocks before uniforms to make it easy to assign block indices to fields 1582 if(!linkUniformBlocks(vertexShader, fragmentShader)) 1583 { 1584 return; 1585 } 1586 1587 if(!linkUniforms(fragmentShader)) 1588 { 1589 return; 1590 } 1591 1592 if(!linkUniforms(vertexShader)) 1593 { 1594 return; 1595 } 1596 1597 if(!linkTransformFeedback()) 1598 { 1599 return; 1600 } 1601 1602 linked = true; // Success 1603 } 1604 1605 // Determines the mapping between GL attributes and vertex stream usage indices 1606 bool Program::linkAttributes() 1607 { 1608 unsigned int usedLocations = 0; 1609 1610 // Link attributes that have a binding location 1611 for(auto const &attribute : vertexShader->activeAttributes) 1612 { 1613 int location = (attributeBinding.find(attribute.name) != attributeBinding.end()) ? attributeBinding[attribute.name] : -1; 1614 1615 if(location != -1) // Set by glBindAttribLocation 1616 { 1617 int rows = VariableRegisterCount(attribute.type); 1618 1619 if(rows + location > MAX_VERTEX_ATTRIBS) 1620 { 1621 appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute.name.c_str(), location); 1622 return false; 1623 } 1624 1625 // In GLSL 3.00, attribute aliasing produces a link error 1626 // In GLSL 1.00, attribute aliasing is allowed 1627 if(vertexShader->getShaderVersion() >= 300) 1628 { 1629 for(auto const &it : linkedAttribute) 1630 { 1631 int itLocStart = getAttributeBinding(it); 1632 ASSERT(itLocStart >= 0); 1633 int itLocEnd = itLocStart + VariableRegisterCount(it.type); 1634 for(int i = 0; i < rows; i++) 1635 { 1636 int loc = location + i; 1637 if((loc >= itLocStart) && (loc < itLocEnd)) 1638 { 1639 appendToInfoLog("Attribute '%s' aliases attribute '%s' at location %d", attribute.name.c_str(), it.name.c_str(), location); 1640 return false; 1641 } 1642 } 1643 } 1644 } 1645 1646 linkedAttributeLocation[attribute.name] = location; 1647 linkedAttribute.push_back(attribute); 1648 for(int i = 0; i < rows; i++) 1649 { 1650 usedLocations |= 1 << (location + i); 1651 } 1652 } 1653 } 1654 1655 // Link attributes that don't have a binding location 1656 for(auto const &attribute : vertexShader->activeAttributes) 1657 { 1658 int location = (attributeBinding.find(attribute.name) != attributeBinding.end()) ? attributeBinding[attribute.name] : -1; 1659 1660 if(location == -1) // Not set by glBindAttribLocation 1661 { 1662 int rows = VariableRegisterCount(attribute.type); 1663 int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS); 1664 1665 if(availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS) 1666 { 1667 appendToInfoLog("Too many active attributes (%s)", attribute.name.c_str()); 1668 return false; // Fail to link 1669 } 1670 1671 linkedAttributeLocation[attribute.name] = availableIndex; 1672 linkedAttribute.push_back(attribute); 1673 } 1674 } 1675 1676 for(auto const &it : linkedAttribute) 1677 { 1678 int location = getAttributeBinding(it); 1679 ASSERT(location >= 0); 1680 int index = vertexShader->getSemanticIndex(it.name); 1681 int rows = std::max(VariableRegisterCount(it.type), 1); 1682 1683 for(int r = 0; r < rows; r++) 1684 { 1685 attributeStream[r + location] = index++; 1686 } 1687 } 1688 1689 return true; 1690 } 1691 1692 int Program::getAttributeBinding(const glsl::Attribute &attribute) 1693 { 1694 if(attribute.location != -1) 1695 { 1696 return attribute.location; 1697 } 1698 1699 std::map<std::string, GLuint>::const_iterator it = linkedAttributeLocation.find(attribute.name); 1700 if(it != linkedAttributeLocation.end()) 1701 { 1702 return it->second; 1703 } 1704 1705 return -1; 1706 } 1707 1708 bool Program::linkUniforms(const Shader *shader) 1709 { 1710 for(const auto &uniform : shader->activeUniforms) 1711 { 1712 unsigned int blockIndex = GL_INVALID_INDEX; 1713 if(uniform.blockId >= 0) 1714 { 1715 const glsl::ActiveUniformBlocks &activeUniformBlocks = shader->activeUniformBlocks; 1716 ASSERT(static_cast<size_t>(uniform.blockId) < activeUniformBlocks.size()); 1717 blockIndex = getUniformBlockIndex(activeUniformBlocks[uniform.blockId].name); 1718 ASSERT(blockIndex != GL_INVALID_INDEX); 1719 } 1720 if(!defineUniform(shader->getType(), uniform, Uniform::BlockInfo(uniform, blockIndex))) 1721 { 1722 return false; 1723 } 1724 } 1725 1726 for(const auto &uniformStruct : shader->activeUniformStructs) 1727 { 1728 if(!validateUniformStruct(shader->getType(), uniformStruct)) 1729 { 1730 return false; 1731 } 1732 } 1733 1734 return true; 1735 } 1736 1737 bool Program::defineUniform(GLenum shader, const glsl::Uniform &glslUniform, const Uniform::BlockInfo& blockInfo) 1738 { 1739 if(IsSamplerUniform(glslUniform.type)) 1740 { 1741 int index = glslUniform.registerIndex; 1742 1743 do 1744 { 1745 if(shader == GL_VERTEX_SHADER) 1746 { 1747 if(index < MAX_VERTEX_TEXTURE_IMAGE_UNITS) 1748 { 1749 samplersVS[index].active = true; 1750 1751 switch(glslUniform.type) 1752 { 1753 default: UNREACHABLE(glslUniform.type); 1754 case GL_INT_SAMPLER_2D: 1755 case GL_UNSIGNED_INT_SAMPLER_2D: 1756 case GL_SAMPLER_2D_SHADOW: 1757 case GL_SAMPLER_2D: samplersVS[index].textureType = TEXTURE_2D; break; 1758 case GL_INT_SAMPLER_CUBE: 1759 case GL_UNSIGNED_INT_SAMPLER_CUBE: 1760 case GL_SAMPLER_CUBE_SHADOW: 1761 case GL_SAMPLER_CUBE: samplersVS[index].textureType = TEXTURE_CUBE; break; 1762 case GL_INT_SAMPLER_3D: 1763 case GL_UNSIGNED_INT_SAMPLER_3D: 1764 case GL_SAMPLER_3D_OES: samplersVS[index].textureType = TEXTURE_3D; break; 1765 case GL_SAMPLER_2D_RECT_ARB: samplersVS[index].textureType = TEXTURE_2D_RECT; break; 1766 case GL_SAMPLER_EXTERNAL_OES: samplersVS[index].textureType = TEXTURE_EXTERNAL; break; 1767 case GL_INT_SAMPLER_2D_ARRAY: 1768 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 1769 case GL_SAMPLER_2D_ARRAY_SHADOW: 1770 case GL_SAMPLER_2D_ARRAY: samplersVS[index].textureType = TEXTURE_2D_ARRAY; break; 1771 } 1772 1773 samplersVS[index].logicalTextureUnit = 0; 1774 } 1775 else 1776 { 1777 appendToInfoLog("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", MAX_VERTEX_TEXTURE_IMAGE_UNITS); 1778 return false; 1779 } 1780 } 1781 else if(shader == GL_FRAGMENT_SHADER) 1782 { 1783 if(index < MAX_TEXTURE_IMAGE_UNITS) 1784 { 1785 samplersPS[index].active = true; 1786 1787 switch(glslUniform.type) 1788 { 1789 default: UNREACHABLE(glslUniform.type); 1790 case GL_INT_SAMPLER_2D: 1791 case GL_UNSIGNED_INT_SAMPLER_2D: 1792 case GL_SAMPLER_2D_SHADOW: 1793 case GL_SAMPLER_2D: samplersPS[index].textureType = TEXTURE_2D; break; 1794 case GL_INT_SAMPLER_CUBE: 1795 case GL_UNSIGNED_INT_SAMPLER_CUBE: 1796 case GL_SAMPLER_CUBE_SHADOW: 1797 case GL_SAMPLER_CUBE: samplersPS[index].textureType = TEXTURE_CUBE; break; 1798 case GL_INT_SAMPLER_3D: 1799 case GL_UNSIGNED_INT_SAMPLER_3D: 1800 case GL_SAMPLER_3D_OES: samplersPS[index].textureType = TEXTURE_3D; break; 1801 case GL_SAMPLER_2D_RECT_ARB: samplersPS[index].textureType = TEXTURE_2D_RECT; break; 1802 case GL_SAMPLER_EXTERNAL_OES: samplersPS[index].textureType = TEXTURE_EXTERNAL; break; 1803 case GL_INT_SAMPLER_2D_ARRAY: 1804 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 1805 case GL_SAMPLER_2D_ARRAY_SHADOW: 1806 case GL_SAMPLER_2D_ARRAY: samplersPS[index].textureType = TEXTURE_2D_ARRAY; break; 1807 } 1808 1809 samplersPS[index].logicalTextureUnit = 0; 1810 } 1811 else 1812 { 1813 appendToInfoLog("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS); 1814 return false; 1815 } 1816 } 1817 else UNREACHABLE(shader); 1818 1819 index++; 1820 } 1821 while(index < glslUniform.registerIndex + static_cast<int>(glslUniform.arraySize)); 1822 } 1823 1824 Uniform *uniform = 0; 1825 GLint location = getUniformLocation(glslUniform.name); 1826 1827 if(location >= 0) // Previously defined, types must match 1828 { 1829 uniform = uniforms[uniformIndex[location].index]; 1830 1831 if(uniform->type != glslUniform.type) 1832 { 1833 appendToInfoLog("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str()); 1834 return false; 1835 } 1836 1837 if(uniform->precision != glslUniform.precision) 1838 { 1839 appendToInfoLog("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str()); 1840 return false; 1841 } 1842 1843 if(!areMatchingFields(uniform->fields, glslUniform.fields, uniform->name)) 1844 { 1845 return false; 1846 } 1847 } 1848 else 1849 { 1850 uniform = new Uniform(glslUniform, blockInfo); 1851 } 1852 1853 if(!uniform) 1854 { 1855 return false; 1856 } 1857 1858 if(shader == GL_VERTEX_SHADER) 1859 { 1860 uniform->vsRegisterIndex = glslUniform.registerIndex; 1861 } 1862 else if(shader == GL_FRAGMENT_SHADER) 1863 { 1864 uniform->psRegisterIndex = glslUniform.registerIndex; 1865 } 1866 else UNREACHABLE(shader); 1867 1868 if(!isUniformDefined(glslUniform.name)) 1869 { 1870 uniforms.push_back(uniform); 1871 unsigned int index = (blockInfo.index == -1) ? static_cast<unsigned int>(uniforms.size() - 1) : GL_INVALID_INDEX; 1872 1873 for(int i = 0; i < uniform->size(); i++) 1874 { 1875 uniformIndex.push_back(UniformLocation(glslUniform.name, i, index)); 1876 } 1877 } 1878 1879 if(shader == GL_VERTEX_SHADER) 1880 { 1881 if(glslUniform.registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS) 1882 { 1883 appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS); 1884 return false; 1885 } 1886 } 1887 else if(shader == GL_FRAGMENT_SHADER) 1888 { 1889 if(glslUniform.registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS) 1890 { 1891 appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS); 1892 return false; 1893 } 1894 } 1895 else UNREACHABLE(shader); 1896 1897 return true; 1898 } 1899 1900 bool Program::validateUniformStruct(GLenum shader, const glsl::Uniform &newUniformStruct) 1901 { 1902 for(const auto &uniformStruct : uniformStructs) 1903 { 1904 if(uniformStruct.name == newUniformStruct.name) 1905 { 1906 return areMatchingFields(uniformStruct.fields, newUniformStruct.fields, newUniformStruct.name); 1907 } 1908 } 1909 1910 uniformStructs.push_back(Uniform(newUniformStruct, Uniform::BlockInfo(newUniformStruct, -1))); 1911 1912 return true; 1913 } 1914 1915 bool Program::areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2) 1916 { 1917 // validate blocks for the same member types 1918 if(block1.fields.size() != block2.fields.size()) 1919 { 1920 appendToInfoLog("Types for interface block '%s' differ between vertex and fragment shaders", block1.name.c_str()); 1921 return false; 1922 } 1923 if(block1.arraySize != block2.arraySize) 1924 { 1925 appendToInfoLog("Array sizes differ for interface block '%s' between vertex and fragment shaders", block1.name.c_str()); 1926 return false; 1927 } 1928 if(block1.layout != block2.layout || block1.isRowMajorLayout != block2.isRowMajorLayout) 1929 { 1930 appendToInfoLog("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", block1.name.c_str()); 1931 return false; 1932 } 1933 const size_t numBlockMembers = block1.fields.size(); 1934 for(size_t blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++) 1935 { 1936 const glsl::Uniform& member1 = shader1->activeUniforms[block1.fields[blockMemberIndex]]; 1937 const glsl::Uniform& member2 = shader2->activeUniforms[block2.fields[blockMemberIndex]]; 1938 if(member1.name != member2.name) 1939 { 1940 appendToInfoLog("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')", 1941 blockMemberIndex, block1.name.c_str(), member1.name.c_str(), member2.name.c_str()); 1942 return false; 1943 } 1944 if(member1.arraySize != member2.arraySize) 1945 { 1946 appendToInfoLog("Array sizes for %s differ between vertex and fragment shaders", member1.name.c_str()); 1947 return false; 1948 } 1949 if(member1.precision != member2.precision) 1950 { 1951 appendToInfoLog("Precisions for %s differ between vertex and fragment shaders", member1.name.c_str()); 1952 return false; 1953 } 1954 if(member1.type != member2.type) 1955 { 1956 appendToInfoLog("Types for %s differ between vertex and fragment shaders", member1.name.c_str()); 1957 return false; 1958 } 1959 if(member1.blockInfo.isRowMajorMatrix != member2.blockInfo.isRowMajorMatrix) 1960 { 1961 appendToInfoLog("Matrix packings for %s differ between vertex and fragment shaders", member1.name.c_str()); 1962 return false; 1963 } 1964 } 1965 return true; 1966 } 1967 1968 bool Program::areMatchingFields(const std::vector<glsl::ShaderVariable>& fields1, const std::vector<glsl::ShaderVariable>& fields2, const std::string& name) 1969 { 1970 if(fields1.size() != fields2.size()) 1971 { 1972 appendToInfoLog("Structure lengths for %s differ between vertex and fragment shaders", name.c_str()); 1973 return false; 1974 } 1975 1976 for(size_t i = 0; i < fields1.size(); ++i) 1977 { 1978 if(fields1[i].name != fields2[i].name) 1979 { 1980 appendToInfoLog("Name mismatch for field '%d' of %s: ('%s', '%s')", 1981 i, name.c_str(), fields1[i].name.c_str(), fields2[i].name.c_str()); 1982 return false; 1983 } 1984 if(fields1[i].type != fields2[i].type) 1985 { 1986 appendToInfoLog("Type for %s.%s differ between vertex and fragment shaders", name.c_str(), fields1[i].name.c_str()); 1987 return false; 1988 } 1989 if(fields1[i].arraySize != fields2[i].arraySize) 1990 { 1991 appendToInfoLog("Array size for %s.%s differ between vertex and fragment shaders", name.c_str(), fields1[i].name.c_str()); 1992 return false; 1993 } 1994 if(!areMatchingFields(fields1[i].fields, fields2[i].fields, fields1[i].name)) 1995 { 1996 return false; 1997 } 1998 } 1999 2000 return true; 2001 } 2002 2003 bool Program::linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader) 2004 { 2005 const glsl::ActiveUniformBlocks &vertexUniformBlocks = vertexShader->activeUniformBlocks; 2006 const glsl::ActiveUniformBlocks &fragmentUniformBlocks = fragmentShader->activeUniformBlocks; 2007 // Check that interface blocks defined in the vertex and fragment shaders are identical 2008 typedef std::map<std::string, const glsl::UniformBlock*> UniformBlockMap; 2009 UniformBlockMap linkedUniformBlocks; 2010 for(unsigned int blockIndex = 0; blockIndex < vertexUniformBlocks.size(); blockIndex++) 2011 { 2012 const glsl::UniformBlock &vertexUniformBlock = vertexUniformBlocks[blockIndex]; 2013 linkedUniformBlocks[vertexUniformBlock.name] = &vertexUniformBlock; 2014 } 2015 for(unsigned int blockIndex = 0; blockIndex < fragmentUniformBlocks.size(); blockIndex++) 2016 { 2017 const glsl::UniformBlock &fragmentUniformBlock = fragmentUniformBlocks[blockIndex]; 2018 UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentUniformBlock.name); 2019 if(entry != linkedUniformBlocks.end()) 2020 { 2021 const glsl::UniformBlock &vertexUniformBlock = *entry->second; 2022 if(!areMatchingUniformBlocks(vertexUniformBlock, fragmentUniformBlock, vertexShader, fragmentShader)) 2023 { 2024 return false; 2025 } 2026 } 2027 } 2028 for(unsigned int blockIndex = 0; blockIndex < vertexUniformBlocks.size(); blockIndex++) 2029 { 2030 const glsl::UniformBlock &uniformBlock = vertexUniformBlocks[blockIndex]; 2031 if(!defineUniformBlock(vertexShader, uniformBlock)) 2032 { 2033 return false; 2034 } 2035 } 2036 for(unsigned int blockIndex = 0; blockIndex < fragmentUniformBlocks.size(); blockIndex++) 2037 { 2038 const glsl::UniformBlock &uniformBlock = fragmentUniformBlocks[blockIndex]; 2039 if(!defineUniformBlock(fragmentShader, uniformBlock)) 2040 { 2041 return false; 2042 } 2043 } 2044 return true; 2045 } 2046 2047 bool Program::defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block) 2048 { 2049 GLuint blockIndex = getUniformBlockIndex(block.name); 2050 2051 if(blockIndex == GL_INVALID_INDEX) 2052 { 2053 const std::vector<int>& fields = block.fields; 2054 std::vector<unsigned int> memberUniformIndexes; 2055 for(size_t i = 0; i < fields.size(); ++i) 2056 { 2057 memberUniformIndexes.push_back(fields[i]); 2058 } 2059 2060 if(block.arraySize > 0) 2061 { 2062 int regIndex = block.registerIndex; 2063 int regInc = block.dataSize / (glsl::BlockLayoutEncoder::BytesPerComponent * glsl::BlockLayoutEncoder::ComponentsPerRegister); 2064 for(unsigned int i = 0; i < block.arraySize; ++i, regIndex += regInc) 2065 { 2066 uniformBlocks.push_back(new UniformBlock(block.name, i, block.dataSize, memberUniformIndexes)); 2067 uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), regIndex); 2068 } 2069 } 2070 else 2071 { 2072 uniformBlocks.push_back(new UniformBlock(block.name, GL_INVALID_INDEX, block.dataSize, memberUniformIndexes)); 2073 uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), block.registerIndex); 2074 } 2075 } 2076 else 2077 { 2078 int regIndex = block.registerIndex; 2079 int regInc = block.dataSize / (glsl::BlockLayoutEncoder::BytesPerComponent * glsl::BlockLayoutEncoder::ComponentsPerRegister); 2080 int nbBlocks = (block.arraySize > 0) ? block.arraySize : 1; 2081 for(int i = 0; i < nbBlocks; ++i, regIndex += regInc) 2082 { 2083 uniformBlocks[blockIndex + i]->setRegisterIndex(shader->getType(), regIndex); 2084 } 2085 } 2086 2087 return true; 2088 } 2089 2090 bool Program::applyUniform(Device *device, GLint location, float* data) 2091 { 2092 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 2093 2094 if(targetUniform->psRegisterIndex != -1) 2095 { 2096 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, data, targetUniform->registerCount()); 2097 } 2098 2099 if(targetUniform->vsRegisterIndex != -1) 2100 { 2101 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, data, targetUniform->registerCount()); 2102 } 2103 2104 return true; 2105 } 2106 2107 bool Program::applyUniform1bv(Device *device, GLint location, GLsizei count, const GLboolean *v) 2108 { 2109 int vector[MAX_UNIFORM_VECTORS][4]; 2110 2111 for(int i = 0; i < count; i++) 2112 { 2113 vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 2114 vector[i][1] = 0; 2115 vector[i][2] = 0; 2116 vector[i][3] = 0; 2117 2118 v += 1; 2119 } 2120 2121 return applyUniform(device, location, (float*)vector); 2122 } 2123 2124 bool Program::applyUniform2bv(Device *device, GLint location, GLsizei count, const GLboolean *v) 2125 { 2126 int vector[MAX_UNIFORM_VECTORS][4]; 2127 2128 for(int i = 0; i < count; i++) 2129 { 2130 vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 2131 vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 2132 vector[i][2] = 0; 2133 vector[i][3] = 0; 2134 2135 v += 2; 2136 } 2137 2138 return applyUniform(device, location, (float*)vector); 2139 } 2140 2141 bool Program::applyUniform3bv(Device *device, GLint location, GLsizei count, const GLboolean *v) 2142 { 2143 int vector[MAX_UNIFORM_VECTORS][4]; 2144 2145 for(int i = 0; i < count; i++) 2146 { 2147 vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 2148 vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 2149 vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 2150 vector[i][3] = 0; 2151 2152 v += 3; 2153 } 2154 2155 return applyUniform(device, location, (float*)vector); 2156 } 2157 2158 bool Program::applyUniform4bv(Device *device, GLint location, GLsizei count, const GLboolean *v) 2159 { 2160 int vector[MAX_UNIFORM_VECTORS][4]; 2161 2162 for(int i = 0; i < count; i++) 2163 { 2164 vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 2165 vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 2166 vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 2167 vector[i][3] = (v[3] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF); 2168 2169 v += 4; 2170 } 2171 2172 return applyUniform(device, location, (float*)vector); 2173 } 2174 2175 bool Program::applyUniform1fv(Device *device, GLint location, GLsizei count, const GLfloat *v) 2176 { 2177 float vector[MAX_UNIFORM_VECTORS][4]; 2178 2179 for(int i = 0; i < count; i++) 2180 { 2181 vector[i][0] = v[0]; 2182 vector[i][1] = 0; 2183 vector[i][2] = 0; 2184 vector[i][3] = 0; 2185 2186 v += 1; 2187 } 2188 2189 return applyUniform(device, location, (float*)vector); 2190 } 2191 2192 bool Program::applyUniform2fv(Device *device, GLint location, GLsizei count, const GLfloat *v) 2193 { 2194 float vector[MAX_UNIFORM_VECTORS][4]; 2195 2196 for(int i = 0; i < count; i++) 2197 { 2198 vector[i][0] = v[0]; 2199 vector[i][1] = v[1]; 2200 vector[i][2] = 0; 2201 vector[i][3] = 0; 2202 2203 v += 2; 2204 } 2205 2206 return applyUniform(device, location, (float*)vector); 2207 } 2208 2209 bool Program::applyUniform3fv(Device *device, GLint location, GLsizei count, const GLfloat *v) 2210 { 2211 float vector[MAX_UNIFORM_VECTORS][4]; 2212 2213 for(int i = 0; i < count; i++) 2214 { 2215 vector[i][0] = v[0]; 2216 vector[i][1] = v[1]; 2217 vector[i][2] = v[2]; 2218 vector[i][3] = 0; 2219 2220 v += 3; 2221 } 2222 2223 return applyUniform(device, location, (float*)vector); 2224 } 2225 2226 bool Program::applyUniform4fv(Device *device, GLint location, GLsizei count, const GLfloat *v) 2227 { 2228 return applyUniform(device, location, (float*)v); 2229 } 2230 2231 bool Program::applyUniformMatrix2fv(Device *device, GLint location, GLsizei count, const GLfloat *value) 2232 { 2233 float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4]; 2234 2235 for(int i = 0; i < count; i++) 2236 { 2237 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = 0; matrix[i][0][3] = 0; 2238 matrix[i][1][0] = value[2]; matrix[i][1][1] = value[3]; matrix[i][1][2] = 0; matrix[i][1][3] = 0; 2239 2240 value += 4; 2241 } 2242 2243 return applyUniform(device, location, (float*)matrix); 2244 } 2245 2246 bool Program::applyUniformMatrix2x3fv(Device *device, GLint location, GLsizei count, const GLfloat *value) 2247 { 2248 float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4]; 2249 2250 for(int i = 0; i < count; i++) 2251 { 2252 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = value[2]; matrix[i][0][3] = 0; 2253 matrix[i][1][0] = value[3]; matrix[i][1][1] = value[4]; matrix[i][1][2] = value[5]; matrix[i][1][3] = 0; 2254 2255 value += 6; 2256 } 2257 2258 return applyUniform(device, location, (float*)matrix); 2259 } 2260 2261 bool Program::applyUniformMatrix2x4fv(Device *device, GLint location, GLsizei count, const GLfloat *value) 2262 { 2263 float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4]; 2264 2265 for(int i = 0; i < count; i++) 2266 { 2267 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = value[2]; matrix[i][0][3] = value[3]; 2268 matrix[i][1][0] = value[4]; matrix[i][1][1] = value[5]; matrix[i][1][2] = value[6]; matrix[i][1][3] = value[7]; 2269 2270 value += 8; 2271 } 2272 2273 return applyUniform(device, location, (float*)matrix); 2274 } 2275 2276 bool Program::applyUniformMatrix3fv(Device *device, GLint location, GLsizei count, const GLfloat *value) 2277 { 2278 float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4]; 2279 2280 for(int i = 0; i < count; i++) 2281 { 2282 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = value[2]; matrix[i][0][3] = 0; 2283 matrix[i][1][0] = value[3]; matrix[i][1][1] = value[4]; matrix[i][1][2] = value[5]; matrix[i][1][3] = 0; 2284 matrix[i][2][0] = value[6]; matrix[i][2][1] = value[7]; matrix[i][2][2] = value[8]; matrix[i][2][3] = 0; 2285 2286 value += 9; 2287 } 2288 2289 return applyUniform(device, location, (float*)matrix); 2290 } 2291 2292 bool Program::applyUniformMatrix3x2fv(Device *device, GLint location, GLsizei count, const GLfloat *value) 2293 { 2294 float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4]; 2295 2296 for(int i = 0; i < count; i++) 2297 { 2298 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = 0; matrix[i][0][3] = 0; 2299 matrix[i][1][0] = value[2]; matrix[i][1][1] = value[3]; matrix[i][1][2] = 0; matrix[i][1][3] = 0; 2300 matrix[i][2][0] = value[4]; matrix[i][2][1] = value[5]; matrix[i][2][2] = 0; matrix[i][2][3] = 0; 2301 2302 value += 6; 2303 } 2304 2305 return applyUniform(device, location, (float*)matrix); 2306 } 2307 2308 bool Program::applyUniformMatrix3x4fv(Device *device, GLint location, GLsizei count, const GLfloat *value) 2309 { 2310 float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4]; 2311 2312 for(int i = 0; i < count; i++) 2313 { 2314 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = value[2]; matrix[i][0][3] = value[3]; 2315 matrix[i][1][0] = value[4]; matrix[i][1][1] = value[5]; matrix[i][1][2] = value[6]; matrix[i][1][3] = value[7]; 2316 matrix[i][2][0] = value[8]; matrix[i][2][1] = value[9]; matrix[i][2][2] = value[10]; matrix[i][2][3] = value[11]; 2317 2318 value += 12; 2319 } 2320 2321 return applyUniform(device, location, (float*)matrix); 2322 } 2323 2324 bool Program::applyUniformMatrix4fv(Device *device, GLint location, GLsizei count, const GLfloat *value) 2325 { 2326 return applyUniform(device, location, (float*)value); 2327 } 2328 2329 bool Program::applyUniformMatrix4x2fv(Device *device, GLint location, GLsizei count, const GLfloat *value) 2330 { 2331 float matrix[(MAX_UNIFORM_VECTORS + 3) / 4][4][4]; 2332 2333 for(int i = 0; i < count; i++) 2334 { 2335 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = 0; matrix[i][0][3] = 0; 2336 matrix[i][1][0] = value[2]; matrix[i][1][1] = value[3]; matrix[i][1][2] = 0; matrix[i][1][3] = 0; 2337 matrix[i][2][0] = value[4]; matrix[i][2][1] = value[5]; matrix[i][2][2] = 0; matrix[i][2][3] = 0; 2338 matrix[i][3][0] = value[6]; matrix[i][3][1] = value[7]; matrix[i][3][2] = 0; matrix[i][3][3] = 0; 2339 2340 value += 8; 2341 } 2342 2343 return applyUniform(device, location, (float*)matrix); 2344 } 2345 2346 bool Program::applyUniformMatrix4x3fv(Device *device, GLint location, GLsizei count, const GLfloat *value) 2347 { 2348 float matrix[(MAX_UNIFORM_VECTORS + 3) / 4][4][4]; 2349 2350 for(int i = 0; i < count; i++) 2351 { 2352 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = value[2]; matrix[i][0][3] = 0; 2353 matrix[i][1][0] = value[3]; matrix[i][1][1] = value[4]; matrix[i][1][2] = value[5]; matrix[i][1][3] = 0; 2354 matrix[i][2][0] = value[6]; matrix[i][2][1] = value[7]; matrix[i][2][2] = value[8]; matrix[i][2][3] = 0; 2355 matrix[i][3][0] = value[9]; matrix[i][3][1] = value[10]; matrix[i][3][2] = value[11]; matrix[i][3][3] = 0; 2356 2357 value += 12; 2358 } 2359 2360 return applyUniform(device, location, (float*)matrix); 2361 } 2362 2363 bool Program::applyUniform1iv(Device *device, GLint location, GLsizei count, const GLint *v) 2364 { 2365 GLint vector[MAX_UNIFORM_VECTORS][4]; 2366 2367 for(int i = 0; i < count; i++) 2368 { 2369 vector[i][0] = v[i]; 2370 vector[i][1] = 0; 2371 vector[i][2] = 0; 2372 vector[i][3] = 0; 2373 } 2374 2375 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 2376 if(IsSamplerUniform(targetUniform->type)) 2377 { 2378 if(targetUniform->psRegisterIndex != -1) 2379 { 2380 for(int i = 0; i < count; i++) 2381 { 2382 unsigned int samplerIndex = targetUniform->psRegisterIndex + i; 2383 2384 if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS) 2385 { 2386 ASSERT(samplersPS[samplerIndex].active); 2387 samplersPS[samplerIndex].logicalTextureUnit = v[i]; 2388 } 2389 } 2390 } 2391 2392 if(targetUniform->vsRegisterIndex != -1) 2393 { 2394 for(int i = 0; i < count; i++) 2395 { 2396 unsigned int samplerIndex = targetUniform->vsRegisterIndex + i; 2397 2398 if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS) 2399 { 2400 ASSERT(samplersVS[samplerIndex].active); 2401 samplersVS[samplerIndex].logicalTextureUnit = v[i]; 2402 } 2403 } 2404 } 2405 } 2406 else 2407 { 2408 return applyUniform(device, location, (float*)vector); 2409 } 2410 2411 return true; 2412 } 2413 2414 bool Program::applyUniform2iv(Device *device, GLint location, GLsizei count, const GLint *v) 2415 { 2416 GLint vector[MAX_UNIFORM_VECTORS][4]; 2417 2418 for(int i = 0; i < count; i++) 2419 { 2420 vector[i][0] = v[0]; 2421 vector[i][1] = v[1]; 2422 vector[i][2] = 0; 2423 vector[i][3] = 0; 2424 2425 v += 2; 2426 } 2427 2428 return applyUniform(device, location, (float*)vector); 2429 } 2430 2431 bool Program::applyUniform3iv(Device *device, GLint location, GLsizei count, const GLint *v) 2432 { 2433 GLint vector[MAX_UNIFORM_VECTORS][4]; 2434 2435 for(int i = 0; i < count; i++) 2436 { 2437 vector[i][0] = v[0]; 2438 vector[i][1] = v[1]; 2439 vector[i][2] = v[2]; 2440 vector[i][3] = 0; 2441 2442 v += 3; 2443 } 2444 2445 return applyUniform(device, location, (float*)vector); 2446 } 2447 2448 bool Program::applyUniform4iv(Device *device, GLint location, GLsizei count, const GLint *v) 2449 { 2450 GLint vector[MAX_UNIFORM_VECTORS][4]; 2451 2452 for(int i = 0; i < count; i++) 2453 { 2454 vector[i][0] = v[0]; 2455 vector[i][1] = v[1]; 2456 vector[i][2] = v[2]; 2457 vector[i][3] = v[3]; 2458 2459 v += 4; 2460 } 2461 2462 return applyUniform(device, location, (float*)vector); 2463 } 2464 2465 bool Program::applyUniform1uiv(Device *device, GLint location, GLsizei count, const GLuint *v) 2466 { 2467 GLuint vector[MAX_UNIFORM_VECTORS][4]; 2468 2469 for(int i = 0; i < count; i++) 2470 { 2471 vector[i][0] = v[i]; 2472 vector[i][1] = 0; 2473 vector[i][2] = 0; 2474 vector[i][3] = 0; 2475 } 2476 2477 Uniform *targetUniform = uniforms[uniformIndex[location].index]; 2478 if(IsSamplerUniform(targetUniform->type)) 2479 { 2480 if(targetUniform->psRegisterIndex != -1) 2481 { 2482 for(int i = 0; i < count; i++) 2483 { 2484 unsigned int samplerIndex = targetUniform->psRegisterIndex + i; 2485 2486 if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS) 2487 { 2488 ASSERT(samplersPS[samplerIndex].active); 2489 samplersPS[samplerIndex].logicalTextureUnit = v[i]; 2490 } 2491 } 2492 } 2493 2494 if(targetUniform->vsRegisterIndex != -1) 2495 { 2496 for(int i = 0; i < count; i++) 2497 { 2498 unsigned int samplerIndex = targetUniform->vsRegisterIndex + i; 2499 2500 if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS) 2501 { 2502 ASSERT(samplersVS[samplerIndex].active); 2503 samplersVS[samplerIndex].logicalTextureUnit = v[i]; 2504 } 2505 } 2506 } 2507 } 2508 else 2509 { 2510 return applyUniform(device, location, (float*)vector); 2511 } 2512 2513 return true; 2514 } 2515 2516 bool Program::applyUniform2uiv(Device *device, GLint location, GLsizei count, const GLuint *v) 2517 { 2518 GLuint vector[MAX_UNIFORM_VECTORS][4]; 2519 2520 for(int i = 0; i < count; i++) 2521 { 2522 vector[i][0] = v[0]; 2523 vector[i][1] = v[1]; 2524 vector[i][2] = 0; 2525 vector[i][3] = 0; 2526 2527 v += 2; 2528 } 2529 2530 return applyUniform(device, location, (float*)vector); 2531 } 2532 2533 bool Program::applyUniform3uiv(Device *device, GLint location, GLsizei count, const GLuint *v) 2534 { 2535 GLuint vector[MAX_UNIFORM_VECTORS][4]; 2536 2537 for(int i = 0; i < count; i++) 2538 { 2539 vector[i][0] = v[0]; 2540 vector[i][1] = v[1]; 2541 vector[i][2] = v[2]; 2542 vector[i][3] = 0; 2543 2544 v += 3; 2545 } 2546 2547 return applyUniform(device, location, (float*)vector); 2548 } 2549 2550 bool Program::applyUniform4uiv(Device *device, GLint location, GLsizei count, const GLuint *v) 2551 { 2552 GLuint vector[MAX_UNIFORM_VECTORS][4]; 2553 2554 for(int i = 0; i < count; i++) 2555 { 2556 vector[i][0] = v[0]; 2557 vector[i][1] = v[1]; 2558 vector[i][2] = v[2]; 2559 vector[i][3] = v[3]; 2560 2561 v += 4; 2562 } 2563 2564 return applyUniform(device, location, (float*)vector); 2565 } 2566 2567 void Program::appendToInfoLog(const char *format, ...) 2568 { 2569 if(!format) 2570 { 2571 return; 2572 } 2573 2574 char info[1024]; 2575 2576 va_list vararg; 2577 va_start(vararg, format); 2578 vsnprintf(info, sizeof(info), format, vararg); 2579 va_end(vararg); 2580 2581 size_t infoLength = strlen(info); 2582 2583 if(!infoLog) 2584 { 2585 infoLog = new char[infoLength + 2]; 2586 strcpy(infoLog, info); 2587 strcpy(infoLog + infoLength, "\n"); 2588 } 2589 else 2590 { 2591 size_t logLength = strlen(infoLog); 2592 char *newLog = new char[logLength + infoLength + 2]; 2593 strcpy(newLog, infoLog); 2594 strcpy(newLog + logLength, info); 2595 strcpy(newLog + logLength + infoLength, "\n"); 2596 2597 delete[] infoLog; 2598 infoLog = newLog; 2599 } 2600 } 2601 2602 void Program::resetInfoLog() 2603 { 2604 if(infoLog) 2605 { 2606 delete[] infoLog; 2607 infoLog = 0; 2608 } 2609 } 2610 2611 // Returns the program object to an unlinked state, before re-linking, or at destruction 2612 void Program::unlink() 2613 { 2614 delete vertexBinary; 2615 vertexBinary = 0; 2616 delete pixelBinary; 2617 pixelBinary = 0; 2618 2619 linkedAttribute.clear(); 2620 linkedAttributeLocation.clear(); 2621 2622 for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++) 2623 { 2624 attributeStream[index] = -1; 2625 } 2626 2627 for(int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++) 2628 { 2629 samplersPS[index].active = false; 2630 } 2631 2632 for(int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++) 2633 { 2634 samplersVS[index].active = false; 2635 } 2636 2637 while(!uniforms.empty()) 2638 { 2639 delete uniforms.back(); 2640 uniforms.pop_back(); 2641 } 2642 2643 while(!uniformBlocks.empty()) 2644 { 2645 delete uniformBlocks.back(); 2646 uniformBlocks.pop_back(); 2647 } 2648 2649 uniformIndex.clear(); 2650 transformFeedbackLinkedVaryings.clear(); 2651 2652 delete[] infoLog; 2653 infoLog = 0; 2654 2655 linked = false; 2656 } 2657 2658 bool Program::isLinked() const 2659 { 2660 return linked; 2661 } 2662 2663 bool Program::isValidated() const 2664 { 2665 return validated; 2666 } 2667 2668 GLint Program::getBinaryLength() const 2669 { 2670 UNIMPLEMENTED(); 2671 return 0; 2672 } 2673 2674 void Program::release() 2675 { 2676 referenceCount--; 2677 2678 if(referenceCount == 0 && orphaned) 2679 { 2680 resourceManager->deleteProgram(handle); 2681 } 2682 } 2683 2684 void Program::addRef() 2685 { 2686 referenceCount++; 2687 } 2688 2689 unsigned int Program::getRefCount() const 2690 { 2691 return referenceCount; 2692 } 2693 2694 unsigned int Program::getSerial() const 2695 { 2696 return serial; 2697 } 2698 2699 unsigned int Program::issueSerial() 2700 { 2701 return currentSerial++; 2702 } 2703 2704 size_t Program::getInfoLogLength() const 2705 { 2706 if(!infoLog) 2707 { 2708 return 0; 2709 } 2710 else 2711 { 2712 return strlen(infoLog) + 1; 2713 } 2714 } 2715 2716 void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *buffer) 2717 { 2718 int index = 0; 2719 2720 if(bufSize > 0) 2721 { 2722 if(infoLog) 2723 { 2724 index = std::min(bufSize - 1, (int)strlen(infoLog)); 2725 memcpy(buffer, infoLog, index); 2726 } 2727 2728 buffer[index] = '\0'; 2729 } 2730 2731 if(length) 2732 { 2733 *length = index; 2734 } 2735 } 2736 2737 void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders) 2738 { 2739 int total = 0; 2740 2741 if(vertexShader && (total < maxCount)) 2742 { 2743 shaders[total++] = vertexShader->getName(); 2744 } 2745 2746 if(fragmentShader && (total < maxCount)) 2747 { 2748 shaders[total++] = fragmentShader->getName(); 2749 } 2750 2751 if(count) 2752 { 2753 *count = total; 2754 } 2755 } 2756 2757 void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const 2758 { 2759 ASSERT(index < linkedAttribute.size()); 2760 2761 std::vector<glsl::Attribute>::const_iterator it = linkedAttribute.begin() + index; 2762 2763 if(bufsize > 0) 2764 { 2765 const char *string = it->name.c_str(); 2766 2767 strncpy(name, string, bufsize); 2768 name[bufsize - 1] = '\0'; 2769 2770 if(length) 2771 { 2772 *length = static_cast<GLsizei>(strlen(name)); 2773 } 2774 } 2775 2776 *size = 1; // Always a single 'type' instance 2777 2778 *type = it->type; 2779 } 2780 2781 size_t Program::getActiveAttributeCount() const 2782 { 2783 return linkedAttribute.size(); 2784 } 2785 2786 GLint Program::getActiveAttributeMaxLength() const 2787 { 2788 int maxLength = 0; 2789 2790 std::vector<glsl::Attribute>::const_iterator it = linkedAttribute.begin(); 2791 std::vector<glsl::Attribute>::const_iterator itEnd = linkedAttribute.end(); 2792 for(; it != itEnd; ++it) 2793 { 2794 maxLength = std::max((int)(it->name.length() + 1), maxLength); 2795 } 2796 2797 return maxLength; 2798 } 2799 2800 void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const 2801 { 2802 if(bufsize > 0) 2803 { 2804 std::string string = uniforms[index]->name; 2805 2806 if(uniforms[index]->isArray()) 2807 { 2808 string += "[0]"; 2809 } 2810 2811 strncpy(name, string.c_str(), bufsize); 2812 name[bufsize - 1] = '\0'; 2813 2814 if(length) 2815 { 2816 *length = static_cast<GLsizei>(strlen(name)); 2817 } 2818 } 2819 2820 *size = uniforms[index]->size(); 2821 2822 *type = uniforms[index]->type; 2823 } 2824 2825 size_t Program::getActiveUniformCount() const 2826 { 2827 return uniforms.size(); 2828 } 2829 2830 GLint Program::getActiveUniformMaxLength() const 2831 { 2832 int maxLength = 0; 2833 2834 size_t numUniforms = uniforms.size(); 2835 for(size_t uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++) 2836 { 2837 if(!uniforms[uniformIndex]->name.empty()) 2838 { 2839 int length = (int)(uniforms[uniformIndex]->name.length() + 1); 2840 if(uniforms[uniformIndex]->isArray()) 2841 { 2842 length += 3; // Counting in "[0]". 2843 } 2844 maxLength = std::max(length, maxLength); 2845 } 2846 } 2847 2848 return maxLength; 2849 } 2850 2851 GLint Program::getActiveUniformi(GLuint index, GLenum pname) const 2852 { 2853 const Uniform& uniform = *uniforms[index]; 2854 switch(pname) 2855 { 2856 case GL_UNIFORM_TYPE: return static_cast<GLint>(uniform.type); 2857 case GL_UNIFORM_SIZE: return static_cast<GLint>(uniform.size()); 2858 case GL_UNIFORM_NAME_LENGTH: return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0)); 2859 case GL_UNIFORM_BLOCK_INDEX: return uniform.blockInfo.index; 2860 case GL_UNIFORM_OFFSET: return uniform.blockInfo.offset; 2861 case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride; 2862 case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride; 2863 case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix); 2864 default: 2865 UNREACHABLE(pname); 2866 break; 2867 } 2868 return 0; 2869 } 2870 2871 void Program::getActiveUniformBlockName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const 2872 { 2873 if(index >= getActiveUniformBlockCount()) 2874 { 2875 return error(GL_INVALID_VALUE); 2876 } 2877 2878 const UniformBlock &uniformBlock = *uniformBlocks[index]; 2879 2880 if(bufSize > 0) 2881 { 2882 std::string string = uniformBlock.name; 2883 2884 if(uniformBlock.isArrayElement()) 2885 { 2886 std::ostringstream elementIndex; 2887 elementIndex << uniformBlock.elementIndex; 2888 string += "[" + elementIndex.str() + "]"; 2889 } 2890 2891 strncpy(name, string.c_str(), bufSize); 2892 name[bufSize - 1] = '\0'; 2893 2894 if(length) 2895 { 2896 *length = static_cast<GLsizei>(strlen(name)); 2897 } 2898 } 2899 } 2900 2901 size_t Program::getActiveUniformBlockCount() const 2902 { 2903 return uniformBlocks.size(); 2904 } 2905 2906 GLint Program::getActiveUniformBlockMaxLength() const 2907 { 2908 GLint maxLength = 0; 2909 2910 if(isLinked()) 2911 { 2912 size_t numUniformBlocks = getActiveUniformBlockCount(); 2913 for(size_t uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++) 2914 { 2915 const UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex]; 2916 if(!uniformBlock.name.empty()) 2917 { 2918 GLint length = static_cast<GLint>(uniformBlock.name.length() + 1); 2919 2920 // Counting in "[0]". 2921 const GLint arrayLength = (uniformBlock.isArrayElement() ? 3 : 0); 2922 2923 maxLength = std::max(length + arrayLength, maxLength); 2924 } 2925 } 2926 } 2927 2928 return maxLength; 2929 } 2930 2931 void Program::setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode) 2932 { 2933 transformFeedbackVaryings.resize(count); 2934 for(GLsizei i = 0; i < count; i++) 2935 { 2936 transformFeedbackVaryings[i] = varyings[i]; 2937 } 2938 2939 transformFeedbackBufferMode = bufferMode; 2940 } 2941 2942 void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const 2943 { 2944 if(linked) 2945 { 2946 ASSERT(index < transformFeedbackLinkedVaryings.size()); 2947 const LinkedVarying &varying = transformFeedbackLinkedVaryings[index]; 2948 GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varying.name.length())); 2949 if(length) 2950 { 2951 *length = lastNameIdx; 2952 } 2953 if(size) 2954 { 2955 *size = varying.size; 2956 } 2957 if(type) 2958 { 2959 *type = varying.type; 2960 } 2961 if(name) 2962 { 2963 memcpy(name, varying.name.c_str(), lastNameIdx); 2964 name[lastNameIdx] = '\0'; 2965 } 2966 } 2967 } 2968 2969 GLsizei Program::getTransformFeedbackVaryingCount() const 2970 { 2971 if(linked) 2972 { 2973 return static_cast<GLsizei>(transformFeedbackLinkedVaryings.size()); 2974 } 2975 else 2976 { 2977 return 0; 2978 } 2979 } 2980 2981 GLsizei Program::getTransformFeedbackVaryingMaxLength() const 2982 { 2983 if(linked) 2984 { 2985 GLsizei maxSize = 0; 2986 for(size_t i = 0; i < transformFeedbackLinkedVaryings.size(); i++) 2987 { 2988 const LinkedVarying &varying = transformFeedbackLinkedVaryings[i]; 2989 maxSize = std::max(maxSize, static_cast<GLsizei>(varying.name.length() + 1)); 2990 } 2991 2992 return maxSize; 2993 } 2994 else 2995 { 2996 return 0; 2997 } 2998 } 2999 3000 GLenum Program::getTransformFeedbackBufferMode() const 3001 { 3002 return transformFeedbackBufferMode; 3003 } 3004 3005 void Program::flagForDeletion() 3006 { 3007 orphaned = true; 3008 } 3009 3010 bool Program::isFlaggedForDeletion() const 3011 { 3012 return orphaned; 3013 } 3014 3015 void Program::validate(Device* device) 3016 { 3017 resetInfoLog(); 3018 3019 if(!isLinked()) 3020 { 3021 appendToInfoLog("Program has not been successfully linked."); 3022 validated = false; 3023 } 3024 else 3025 { 3026 applyUniforms(device); 3027 if(!validateSamplers(true)) 3028 { 3029 validated = false; 3030 } 3031 else 3032 { 3033 validated = true; 3034 } 3035 } 3036 } 3037 3038 bool Program::validateSamplers(bool logErrors) 3039 { 3040 // if any two active samplers in a program are of different types, but refer to the same 3041 // texture image unit, and this is the current program, then ValidateProgram will fail, and 3042 // DrawArrays and DrawElements will issue the INVALID_OPERATION error. 3043 3044 TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; 3045 3046 for(unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; i++) 3047 { 3048 textureUnitType[i] = TEXTURE_UNKNOWN; 3049 } 3050 3051 for(unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) 3052 { 3053 if(samplersPS[i].active) 3054 { 3055 unsigned int unit = samplersPS[i].logicalTextureUnit; 3056 3057 if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS) 3058 { 3059 if(logErrors) 3060 { 3061 appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS); 3062 } 3063 3064 return false; 3065 } 3066 3067 if(textureUnitType[unit] != TEXTURE_UNKNOWN) 3068 { 3069 if(samplersPS[i].textureType != textureUnitType[unit]) 3070 { 3071 if(logErrors) 3072 { 3073 appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit); 3074 } 3075 3076 return false; 3077 } 3078 } 3079 else 3080 { 3081 textureUnitType[unit] = samplersPS[i].textureType; 3082 } 3083 } 3084 } 3085 3086 for(unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++) 3087 { 3088 if(samplersVS[i].active) 3089 { 3090 unsigned int unit = samplersVS[i].logicalTextureUnit; 3091 3092 if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS) 3093 { 3094 if(logErrors) 3095 { 3096 appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS); 3097 } 3098 3099 return false; 3100 } 3101 3102 if(textureUnitType[unit] != TEXTURE_UNKNOWN) 3103 { 3104 if(samplersVS[i].textureType != textureUnitType[unit]) 3105 { 3106 if(logErrors) 3107 { 3108 appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit); 3109 } 3110 3111 return false; 3112 } 3113 } 3114 else 3115 { 3116 textureUnitType[unit] = samplersVS[i].textureType; 3117 } 3118 } 3119 } 3120 3121 return true; 3122 } 3123 } 3124