1 #include "precompiled.h" 2 // 3 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style license that can be 5 // found in the LICENSE file. 6 // 7 8 // Program.cpp: Implements the gl::Program class. Implements GL program objects 9 // and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28. 10 11 #include "libGLESv2/BinaryStream.h" 12 #include "libGLESv2/ProgramBinary.h" 13 #include "libGLESv2/renderer/ShaderExecutable.h" 14 15 #include "common/debug.h" 16 #include "common/version.h" 17 #include "utilities.h" 18 19 #include "libGLESv2/main.h" 20 #include "libGLESv2/Shader.h" 21 #include "libGLESv2/Program.h" 22 #include "libGLESv2/renderer/Renderer.h" 23 #include "libGLESv2/renderer/VertexDataManager.h" 24 25 #undef near 26 #undef far 27 28 namespace gl 29 { 30 std::string str(int i) 31 { 32 char buffer[20]; 33 snprintf(buffer, sizeof(buffer), "%d", i); 34 return buffer; 35 } 36 37 UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) 38 : name(name), element(element), index(index) 39 { 40 } 41 42 unsigned int ProgramBinary::mCurrentSerial = 1; 43 44 ProgramBinary::ProgramBinary(rx::Renderer *renderer) : mRenderer(renderer), RefCountObject(0), mSerial(issueSerial()) 45 { 46 mPixelExecutable = NULL; 47 mVertexExecutable = NULL; 48 mGeometryExecutable = NULL; 49 50 mValidated = false; 51 52 for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++) 53 { 54 mSemanticIndex[index] = -1; 55 } 56 57 for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++) 58 { 59 mSamplersPS[index].active = false; 60 } 61 62 for (int index = 0; index < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++) 63 { 64 mSamplersVS[index].active = false; 65 } 66 67 mUsedVertexSamplerRange = 0; 68 mUsedPixelSamplerRange = 0; 69 mUsesPointSize = false; 70 } 71 72 ProgramBinary::~ProgramBinary() 73 { 74 delete mPixelExecutable; 75 mPixelExecutable = NULL; 76 77 delete mVertexExecutable; 78 mVertexExecutable = NULL; 79 80 delete mGeometryExecutable; 81 mGeometryExecutable = NULL; 82 83 while (!mUniforms.empty()) 84 { 85 delete mUniforms.back(); 86 mUniforms.pop_back(); 87 } 88 } 89 90 unsigned int ProgramBinary::getSerial() const 91 { 92 return mSerial; 93 } 94 95 unsigned int ProgramBinary::issueSerial() 96 { 97 return mCurrentSerial++; 98 } 99 100 rx::ShaderExecutable *ProgramBinary::getPixelExecutable() 101 { 102 return mPixelExecutable; 103 } 104 105 rx::ShaderExecutable *ProgramBinary::getVertexExecutable() 106 { 107 return mVertexExecutable; 108 } 109 110 rx::ShaderExecutable *ProgramBinary::getGeometryExecutable() 111 { 112 return mGeometryExecutable; 113 } 114 115 GLuint ProgramBinary::getAttributeLocation(const char *name) 116 { 117 if (name) 118 { 119 for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++) 120 { 121 if (mLinkedAttribute[index].name == std::string(name)) 122 { 123 return index; 124 } 125 } 126 } 127 128 return -1; 129 } 130 131 int ProgramBinary::getSemanticIndex(int attributeIndex) 132 { 133 ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS); 134 135 return mSemanticIndex[attributeIndex]; 136 } 137 138 // Returns one more than the highest sampler index used. 139 GLint ProgramBinary::getUsedSamplerRange(SamplerType type) 140 { 141 switch (type) 142 { 143 case SAMPLER_PIXEL: 144 return mUsedPixelSamplerRange; 145 case SAMPLER_VERTEX: 146 return mUsedVertexSamplerRange; 147 default: 148 UNREACHABLE(); 149 return 0; 150 } 151 } 152 153 bool ProgramBinary::usesPointSize() const 154 { 155 return mUsesPointSize; 156 } 157 158 bool ProgramBinary::usesPointSpriteEmulation() const 159 { 160 return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4; 161 } 162 163 bool ProgramBinary::usesGeometryShader() const 164 { 165 return usesPointSpriteEmulation(); 166 } 167 168 // Returns the index of the texture image unit (0-19) corresponding to a Direct3D 9 sampler 169 // index (0-15 for the pixel shader and 0-3 for the vertex shader). 170 GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex) 171 { 172 GLint logicalTextureUnit = -1; 173 174 switch (type) 175 { 176 case SAMPLER_PIXEL: 177 ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0])); 178 179 if (mSamplersPS[samplerIndex].active) 180 { 181 logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit; 182 } 183 break; 184 case SAMPLER_VERTEX: 185 ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0])); 186 187 if (mSamplersVS[samplerIndex].active) 188 { 189 logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit; 190 } 191 break; 192 default: UNREACHABLE(); 193 } 194 195 if (logicalTextureUnit >= 0 && logicalTextureUnit < (GLint)mRenderer->getMaxCombinedTextureImageUnits()) 196 { 197 return logicalTextureUnit; 198 } 199 200 return -1; 201 } 202 203 // Returns the texture type for a given Direct3D 9 sampler type and 204 // index (0-15 for the pixel shader and 0-3 for the vertex shader). 205 TextureType ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex) 206 { 207 switch (type) 208 { 209 case SAMPLER_PIXEL: 210 ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0])); 211 ASSERT(mSamplersPS[samplerIndex].active); 212 return mSamplersPS[samplerIndex].textureType; 213 case SAMPLER_VERTEX: 214 ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0])); 215 ASSERT(mSamplersVS[samplerIndex].active); 216 return mSamplersVS[samplerIndex].textureType; 217 default: UNREACHABLE(); 218 } 219 220 return TEXTURE_2D; 221 } 222 223 GLint ProgramBinary::getUniformLocation(std::string name) 224 { 225 unsigned int subscript = 0; 226 227 // Strip any trailing array operator and retrieve the subscript 228 size_t open = name.find_last_of('['); 229 size_t close = name.find_last_of(']'); 230 if (open != std::string::npos && close == name.length() - 1) 231 { 232 subscript = atoi(name.substr(open + 1).c_str()); 233 name.erase(open); 234 } 235 236 unsigned int numUniforms = mUniformIndex.size(); 237 for (unsigned int location = 0; location < numUniforms; location++) 238 { 239 if (mUniformIndex[location].name == name && 240 mUniformIndex[location].element == subscript) 241 { 242 return location; 243 } 244 } 245 246 return -1; 247 } 248 249 bool ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) 250 { 251 if (location < 0 || location >= (int)mUniformIndex.size()) 252 { 253 return false; 254 } 255 256 Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; 257 targetUniform->dirty = true; 258 259 int elementCount = targetUniform->elementCount(); 260 261 if (elementCount == 1 && count > 1) 262 return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION 263 264 count = std::min(elementCount - (int)mUniformIndex[location].element, count); 265 266 if (targetUniform->type == GL_FLOAT) 267 { 268 GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; 269 270 for (int i = 0; i < count; i++) 271 { 272 target[0] = v[0]; 273 target[1] = 0; 274 target[2] = 0; 275 target[3] = 0; 276 target += 4; 277 v += 1; 278 } 279 } 280 else if (targetUniform->type == GL_BOOL) 281 { 282 GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; 283 284 for (int i = 0; i < count; i++) 285 { 286 boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE; 287 boolParams[1] = GL_FALSE; 288 boolParams[2] = GL_FALSE; 289 boolParams[3] = GL_FALSE; 290 boolParams += 4; 291 v += 1; 292 } 293 } 294 else 295 { 296 return false; 297 } 298 299 return true; 300 } 301 302 bool ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) 303 { 304 if (location < 0 || location >= (int)mUniformIndex.size()) 305 { 306 return false; 307 } 308 309 Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; 310 targetUniform->dirty = true; 311 312 int elementCount = targetUniform->elementCount(); 313 314 if (elementCount == 1 && count > 1) 315 return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION 316 317 count = std::min(elementCount - (int)mUniformIndex[location].element, count); 318 319 if (targetUniform->type == GL_FLOAT_VEC2) 320 { 321 GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; 322 323 for (int i = 0; i < count; i++) 324 { 325 target[0] = v[0]; 326 target[1] = v[1]; 327 target[2] = 0; 328 target[3] = 0; 329 target += 4; 330 v += 2; 331 } 332 } 333 else if (targetUniform->type == GL_BOOL_VEC2) 334 { 335 GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; 336 337 for (int i = 0; i < count; i++) 338 { 339 boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE; 340 boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE; 341 boolParams[2] = GL_FALSE; 342 boolParams[3] = GL_FALSE; 343 boolParams += 4; 344 v += 2; 345 } 346 } 347 else 348 { 349 return false; 350 } 351 352 return true; 353 } 354 355 bool ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) 356 { 357 if (location < 0 || location >= (int)mUniformIndex.size()) 358 { 359 return false; 360 } 361 362 Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; 363 targetUniform->dirty = true; 364 365 int elementCount = targetUniform->elementCount(); 366 367 if (elementCount == 1 && count > 1) 368 return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION 369 370 count = std::min(elementCount - (int)mUniformIndex[location].element, count); 371 372 if (targetUniform->type == GL_FLOAT_VEC3) 373 { 374 GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; 375 376 for (int i = 0; i < count; i++) 377 { 378 target[0] = v[0]; 379 target[1] = v[1]; 380 target[2] = v[2]; 381 target[3] = 0; 382 target += 4; 383 v += 3; 384 } 385 } 386 else if (targetUniform->type == GL_BOOL_VEC3) 387 { 388 GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; 389 390 for (int i = 0; i < count; i++) 391 { 392 boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE; 393 boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE; 394 boolParams[2] = (v[2] == 0.0f) ? GL_FALSE : GL_TRUE; 395 boolParams[3] = GL_FALSE; 396 boolParams += 4; 397 v += 3; 398 } 399 } 400 else 401 { 402 return false; 403 } 404 405 return true; 406 } 407 408 bool ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) 409 { 410 if (location < 0 || location >= (int)mUniformIndex.size()) 411 { 412 return false; 413 } 414 415 Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; 416 targetUniform->dirty = true; 417 418 int elementCount = targetUniform->elementCount(); 419 420 if (elementCount == 1 && count > 1) 421 return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION 422 423 count = std::min(elementCount - (int)mUniformIndex[location].element, count); 424 425 if (targetUniform->type == GL_FLOAT_VEC4) 426 { 427 GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; 428 429 for (int i = 0; i < count; i++) 430 { 431 target[0] = v[0]; 432 target[1] = v[1]; 433 target[2] = v[2]; 434 target[3] = v[3]; 435 target += 4; 436 v += 4; 437 } 438 } 439 else if (targetUniform->type == GL_BOOL_VEC4) 440 { 441 GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; 442 443 for (int i = 0; i < count; i++) 444 { 445 boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE; 446 boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE; 447 boolParams[2] = (v[2] == 0.0f) ? GL_FALSE : GL_TRUE; 448 boolParams[3] = (v[3] == 0.0f) ? GL_FALSE : GL_TRUE; 449 boolParams += 4; 450 v += 4; 451 } 452 } 453 else 454 { 455 return false; 456 } 457 458 return true; 459 } 460 461 template<typename T, int targetWidth, int targetHeight, int srcWidth, int srcHeight> 462 void transposeMatrix(T *target, const GLfloat *value) 463 { 464 int copyWidth = std::min(targetWidth, srcWidth); 465 int copyHeight = std::min(targetHeight, srcHeight); 466 467 for (int x = 0; x < copyWidth; x++) 468 { 469 for (int y = 0; y < copyHeight; y++) 470 { 471 target[x * targetWidth + y] = (T)value[y * srcWidth + x]; 472 } 473 } 474 // clear unfilled right side 475 for (int y = 0; y < copyHeight; y++) 476 { 477 for (int x = srcWidth; x < targetWidth; x++) 478 { 479 target[y * targetWidth + x] = (T)0; 480 } 481 } 482 // clear unfilled bottom. 483 for (int y = srcHeight; y < targetHeight; y++) 484 { 485 for (int x = 0; x < targetWidth; x++) 486 { 487 target[y * targetWidth + x] = (T)0; 488 } 489 } 490 } 491 492 bool ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) 493 { 494 if (location < 0 || location >= (int)mUniformIndex.size()) 495 { 496 return false; 497 } 498 499 Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; 500 targetUniform->dirty = true; 501 502 if (targetUniform->type != GL_FLOAT_MAT2) 503 { 504 return false; 505 } 506 507 int elementCount = targetUniform->elementCount(); 508 509 if (elementCount == 1 && count > 1) 510 return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION 511 512 count = std::min(elementCount - (int)mUniformIndex[location].element, count); 513 GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8; 514 515 for (int i = 0; i < count; i++) 516 { 517 transposeMatrix<GLfloat,4,2,2,2>(target, value); 518 target += 8; 519 value += 4; 520 } 521 522 return true; 523 } 524 525 bool ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) 526 { 527 if (location < 0 || location >= (int)mUniformIndex.size()) 528 { 529 return false; 530 } 531 532 Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; 533 targetUniform->dirty = true; 534 535 if (targetUniform->type != GL_FLOAT_MAT3) 536 { 537 return false; 538 } 539 540 int elementCount = targetUniform->elementCount(); 541 542 if (elementCount == 1 && count > 1) 543 return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION 544 545 count = std::min(elementCount - (int)mUniformIndex[location].element, count); 546 GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12; 547 548 for (int i = 0; i < count; i++) 549 { 550 transposeMatrix<GLfloat,4,3,3,3>(target, value); 551 target += 12; 552 value += 9; 553 } 554 555 return true; 556 } 557 558 559 bool ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) 560 { 561 if (location < 0 || location >= (int)mUniformIndex.size()) 562 { 563 return false; 564 } 565 566 Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; 567 targetUniform->dirty = true; 568 569 if (targetUniform->type != GL_FLOAT_MAT4) 570 { 571 return false; 572 } 573 574 int elementCount = targetUniform->elementCount(); 575 576 if (elementCount == 1 && count > 1) 577 return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION 578 579 count = std::min(elementCount - (int)mUniformIndex[location].element, count); 580 GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 16); 581 582 for (int i = 0; i < count; i++) 583 { 584 transposeMatrix<GLfloat,4,4,4,4>(target, value); 585 target += 16; 586 value += 16; 587 } 588 589 return true; 590 } 591 592 bool ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) 593 { 594 if (location < 0 || location >= (int)mUniformIndex.size()) 595 { 596 return false; 597 } 598 599 Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; 600 targetUniform->dirty = true; 601 602 int elementCount = targetUniform->elementCount(); 603 604 if (elementCount == 1 && count > 1) 605 return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION 606 607 count = std::min(elementCount - (int)mUniformIndex[location].element, count); 608 609 if (targetUniform->type == GL_INT || 610 targetUniform->type == GL_SAMPLER_2D || 611 targetUniform->type == GL_SAMPLER_CUBE) 612 { 613 GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; 614 615 for (int i = 0; i < count; i++) 616 { 617 target[0] = v[0]; 618 target[1] = 0; 619 target[2] = 0; 620 target[3] = 0; 621 target += 4; 622 v += 1; 623 } 624 } 625 else if (targetUniform->type == GL_BOOL) 626 { 627 GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; 628 629 for (int i = 0; i < count; i++) 630 { 631 boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE; 632 boolParams[1] = GL_FALSE; 633 boolParams[2] = GL_FALSE; 634 boolParams[3] = GL_FALSE; 635 boolParams += 4; 636 v += 1; 637 } 638 } 639 else 640 { 641 return false; 642 } 643 644 return true; 645 } 646 647 bool ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v) 648 { 649 if (location < 0 || location >= (int)mUniformIndex.size()) 650 { 651 return false; 652 } 653 654 Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; 655 targetUniform->dirty = true; 656 657 int elementCount = targetUniform->elementCount(); 658 659 if (elementCount == 1 && count > 1) 660 return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION 661 662 count = std::min(elementCount - (int)mUniformIndex[location].element, count); 663 664 if (targetUniform->type == GL_INT_VEC2) 665 { 666 GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; 667 668 for (int i = 0; i < count; i++) 669 { 670 target[0] = v[0]; 671 target[1] = v[1]; 672 target[2] = 0; 673 target[3] = 0; 674 target += 4; 675 v += 2; 676 } 677 } 678 else if (targetUniform->type == GL_BOOL_VEC2) 679 { 680 GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; 681 682 for (int i = 0; i < count; i++) 683 { 684 boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE; 685 boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE; 686 boolParams[2] = GL_FALSE; 687 boolParams[3] = GL_FALSE; 688 boolParams += 4; 689 v += 2; 690 } 691 } 692 else 693 { 694 return false; 695 } 696 697 return true; 698 } 699 700 bool ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v) 701 { 702 if (location < 0 || location >= (int)mUniformIndex.size()) 703 { 704 return false; 705 } 706 707 Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; 708 targetUniform->dirty = true; 709 710 int elementCount = targetUniform->elementCount(); 711 712 if (elementCount == 1 && count > 1) 713 return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION 714 715 count = std::min(elementCount - (int)mUniformIndex[location].element, count); 716 717 if (targetUniform->type == GL_INT_VEC3) 718 { 719 GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; 720 721 for (int i = 0; i < count; i++) 722 { 723 target[0] = v[0]; 724 target[1] = v[1]; 725 target[2] = v[2]; 726 target[3] = 0; 727 target += 4; 728 v += 3; 729 } 730 } 731 else if (targetUniform->type == GL_BOOL_VEC3) 732 { 733 GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; 734 735 for (int i = 0; i < count; i++) 736 { 737 boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE; 738 boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE; 739 boolParams[2] = (v[2] == 0) ? GL_FALSE : GL_TRUE; 740 boolParams[3] = GL_FALSE; 741 boolParams += 4; 742 v += 3; 743 } 744 } 745 else 746 { 747 return false; 748 } 749 750 return true; 751 } 752 753 bool ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v) 754 { 755 if (location < 0 || location >= (int)mUniformIndex.size()) 756 { 757 return false; 758 } 759 760 Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; 761 targetUniform->dirty = true; 762 763 int elementCount = targetUniform->elementCount(); 764 765 if (elementCount == 1 && count > 1) 766 return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION 767 768 count = std::min(elementCount - (int)mUniformIndex[location].element, count); 769 770 if (targetUniform->type == GL_INT_VEC4) 771 { 772 GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; 773 774 for (int i = 0; i < count; i++) 775 { 776 target[0] = v[0]; 777 target[1] = v[1]; 778 target[2] = v[2]; 779 target[3] = v[3]; 780 target += 4; 781 v += 4; 782 } 783 } 784 else if (targetUniform->type == GL_BOOL_VEC4) 785 { 786 GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; 787 788 for (int i = 0; i < count; i++) 789 { 790 boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE; 791 boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE; 792 boolParams[2] = (v[2] == 0) ? GL_FALSE : GL_TRUE; 793 boolParams[3] = (v[3] == 0) ? GL_FALSE : GL_TRUE; 794 boolParams += 4; 795 v += 4; 796 } 797 } 798 else 799 { 800 return false; 801 } 802 803 return true; 804 } 805 806 bool ProgramBinary::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params) 807 { 808 if (location < 0 || location >= (int)mUniformIndex.size()) 809 { 810 return false; 811 } 812 813 Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; 814 815 // sized queries -- ensure the provided buffer is large enough 816 if (bufSize) 817 { 818 int requiredBytes = UniformExternalSize(targetUniform->type); 819 if (*bufSize < requiredBytes) 820 { 821 return false; 822 } 823 } 824 825 switch (targetUniform->type) 826 { 827 case GL_FLOAT_MAT2: 828 transposeMatrix<GLfloat,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8); 829 break; 830 case GL_FLOAT_MAT3: 831 transposeMatrix<GLfloat,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12); 832 break; 833 case GL_FLOAT_MAT4: 834 transposeMatrix<GLfloat,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16); 835 break; 836 default: 837 { 838 unsigned int size = UniformComponentCount(targetUniform->type); 839 840 switch (UniformComponentType(targetUniform->type)) 841 { 842 case GL_BOOL: 843 { 844 GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; 845 846 for (unsigned int i = 0; i < size; i++) 847 { 848 params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f; 849 } 850 } 851 break; 852 case GL_FLOAT: 853 memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(GLfloat), 854 size * sizeof(GLfloat)); 855 break; 856 case GL_INT: 857 { 858 GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; 859 860 for (unsigned int i = 0; i < size; i++) 861 { 862 params[i] = (float)intParams[i]; 863 } 864 } 865 break; 866 default: UNREACHABLE(); 867 } 868 } 869 } 870 871 return true; 872 } 873 874 bool ProgramBinary::getUniformiv(GLint location, GLsizei *bufSize, GLint *params) 875 { 876 if (location < 0 || location >= (int)mUniformIndex.size()) 877 { 878 return false; 879 } 880 881 Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; 882 883 // sized queries -- ensure the provided buffer is large enough 884 if (bufSize) 885 { 886 int requiredBytes = UniformExternalSize(targetUniform->type); 887 if (*bufSize < requiredBytes) 888 { 889 return false; 890 } 891 } 892 893 switch (targetUniform->type) 894 { 895 case GL_FLOAT_MAT2: 896 transposeMatrix<GLint,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8); 897 break; 898 case GL_FLOAT_MAT3: 899 transposeMatrix<GLint,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12); 900 break; 901 case GL_FLOAT_MAT4: 902 transposeMatrix<GLint,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16); 903 break; 904 default: 905 { 906 unsigned int size = VariableColumnCount(targetUniform->type); 907 908 switch (UniformComponentType(targetUniform->type)) 909 { 910 case GL_BOOL: 911 { 912 GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; 913 914 for (unsigned int i = 0; i < size; i++) 915 { 916 params[i] = boolParams[i]; 917 } 918 } 919 break; 920 case GL_FLOAT: 921 { 922 GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; 923 924 for (unsigned int i = 0; i < size; i++) 925 { 926 params[i] = (GLint)floatParams[i]; 927 } 928 } 929 break; 930 case GL_INT: 931 memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(GLint), 932 size * sizeof(GLint)); 933 break; 934 default: UNREACHABLE(); 935 } 936 } 937 } 938 939 return true; 940 } 941 942 void ProgramBinary::dirtyAllUniforms() 943 { 944 unsigned int numUniforms = mUniforms.size(); 945 for (unsigned int index = 0; index < numUniforms; index++) 946 { 947 mUniforms[index]->dirty = true; 948 } 949 } 950 951 // Applies all the uniforms set for this program object to the renderer 952 void ProgramBinary::applyUniforms() 953 { 954 // Retrieve sampler uniform values 955 for (std::vector<Uniform*>::iterator ub = mUniforms.begin(), ue = mUniforms.end(); ub != ue; ++ub) 956 { 957 Uniform *targetUniform = *ub; 958 959 if (targetUniform->dirty) 960 { 961 if (targetUniform->type == GL_SAMPLER_2D || 962 targetUniform->type == GL_SAMPLER_CUBE) 963 { 964 int count = targetUniform->elementCount(); 965 GLint (*v)[4] = (GLint(*)[4])targetUniform->data; 966 967 if (targetUniform->psRegisterIndex >= 0) 968 { 969 unsigned int firstIndex = targetUniform->psRegisterIndex; 970 971 for (int i = 0; i < count; i++) 972 { 973 unsigned int samplerIndex = firstIndex + i; 974 975 if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS) 976 { 977 ASSERT(mSamplersPS[samplerIndex].active); 978 mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0]; 979 } 980 } 981 } 982 983 if (targetUniform->vsRegisterIndex >= 0) 984 { 985 unsigned int firstIndex = targetUniform->vsRegisterIndex; 986 987 for (int i = 0; i < count; i++) 988 { 989 unsigned int samplerIndex = firstIndex + i; 990 991 if (samplerIndex < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS) 992 { 993 ASSERT(mSamplersVS[samplerIndex].active); 994 mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0]; 995 } 996 } 997 } 998 } 999 } 1000 } 1001 1002 mRenderer->applyUniforms(this, &mUniforms); 1003 } 1004 1005 // Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111 1006 // Returns the number of used varying registers, or -1 if unsuccesful 1007 int ProgramBinary::packVaryings(InfoLog &infoLog, const Varying *packing[][4], FragmentShader *fragmentShader) 1008 { 1009 const int maxVaryingVectors = mRenderer->getMaxVaryingVectors(); 1010 1011 fragmentShader->resetVaryingsRegisterAssignment(); 1012 1013 for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++) 1014 { 1015 int n = VariableRowCount(varying->type) * varying->size; 1016 int m = VariableColumnCount(varying->type); 1017 bool success = false; 1018 1019 if (m == 2 || m == 3 || m == 4) 1020 { 1021 for (int r = 0; r <= maxVaryingVectors - n && !success; r++) 1022 { 1023 bool available = true; 1024 1025 for (int y = 0; y < n && available; y++) 1026 { 1027 for (int x = 0; x < m && available; x++) 1028 { 1029 if (packing[r + y][x]) 1030 { 1031 available = false; 1032 } 1033 } 1034 } 1035 1036 if (available) 1037 { 1038 varying->reg = r; 1039 varying->col = 0; 1040 1041 for (int y = 0; y < n; y++) 1042 { 1043 for (int x = 0; x < m; x++) 1044 { 1045 packing[r + y][x] = &*varying; 1046 } 1047 } 1048 1049 success = true; 1050 } 1051 } 1052 1053 if (!success && m == 2) 1054 { 1055 for (int r = maxVaryingVectors - n; r >= 0 && !success; r--) 1056 { 1057 bool available = true; 1058 1059 for (int y = 0; y < n && available; y++) 1060 { 1061 for (int x = 2; x < 4 && available; x++) 1062 { 1063 if (packing[r + y][x]) 1064 { 1065 available = false; 1066 } 1067 } 1068 } 1069 1070 if (available) 1071 { 1072 varying->reg = r; 1073 varying->col = 2; 1074 1075 for (int y = 0; y < n; y++) 1076 { 1077 for (int x = 2; x < 4; x++) 1078 { 1079 packing[r + y][x] = &*varying; 1080 } 1081 } 1082 1083 success = true; 1084 } 1085 } 1086 } 1087 } 1088 else if (m == 1) 1089 { 1090 int space[4] = {0}; 1091 1092 for (int y = 0; y < maxVaryingVectors; y++) 1093 { 1094 for (int x = 0; x < 4; x++) 1095 { 1096 space[x] += packing[y][x] ? 0 : 1; 1097 } 1098 } 1099 1100 int column = 0; 1101 1102 for (int x = 0; x < 4; x++) 1103 { 1104 if (space[x] >= n && space[x] < space[column]) 1105 { 1106 column = x; 1107 } 1108 } 1109 1110 if (space[column] >= n) 1111 { 1112 for (int r = 0; r < maxVaryingVectors; r++) 1113 { 1114 if (!packing[r][column]) 1115 { 1116 varying->reg = r; 1117 1118 for (int y = r; y < r + n; y++) 1119 { 1120 packing[y][column] = &*varying; 1121 } 1122 1123 break; 1124 } 1125 } 1126 1127 varying->col = column; 1128 1129 success = true; 1130 } 1131 } 1132 else UNREACHABLE(); 1133 1134 if (!success) 1135 { 1136 infoLog.append("Could not pack varying %s", varying->name.c_str()); 1137 1138 return -1; 1139 } 1140 } 1141 1142 // Return the number of used registers 1143 int registers = 0; 1144 1145 for (int r = 0; r < maxVaryingVectors; r++) 1146 { 1147 if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3]) 1148 { 1149 registers++; 1150 } 1151 } 1152 1153 return registers; 1154 } 1155 1156 bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying *packing[][4], 1157 std::string& pixelHLSL, std::string& vertexHLSL, 1158 FragmentShader *fragmentShader, VertexShader *vertexShader) 1159 { 1160 if (pixelHLSL.empty() || vertexHLSL.empty()) 1161 { 1162 return false; 1163 } 1164 1165 bool usesMRT = fragmentShader->mUsesMultipleRenderTargets; 1166 bool usesFragColor = fragmentShader->mUsesFragColor; 1167 bool usesFragData = fragmentShader->mUsesFragData; 1168 if (usesFragColor && usesFragData) 1169 { 1170 infoLog.append("Cannot use both gl_FragColor and gl_FragData in the same fragment shader."); 1171 return false; 1172 } 1173 1174 // Write the HLSL input/output declarations 1175 const int shaderModel = mRenderer->getMajorShaderModel(); 1176 const int maxVaryingVectors = mRenderer->getMaxVaryingVectors(); 1177 1178 const int registersNeeded = registers + (fragmentShader->mUsesFragCoord ? 1 : 0) + (fragmentShader->mUsesPointCoord ? 1 : 0); 1179 1180 // The output color is broadcast to all enabled draw buffers when writing to gl_FragColor 1181 const bool broadcast = fragmentShader->mUsesFragColor; 1182 const unsigned int numRenderTargets = (broadcast || usesMRT ? mRenderer->getMaxRenderTargets() : 1); 1183 1184 if (registersNeeded > maxVaryingVectors) 1185 { 1186 infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord"); 1187 1188 return false; 1189 } 1190 1191 vertexShader->resetVaryingsRegisterAssignment(); 1192 1193 for (VaryingList::iterator input = fragmentShader->mVaryings.begin(); input != fragmentShader->mVaryings.end(); input++) 1194 { 1195 bool matched = false; 1196 1197 for (VaryingList::iterator output = vertexShader->mVaryings.begin(); output != vertexShader->mVaryings.end(); output++) 1198 { 1199 if (output->name == input->name) 1200 { 1201 if (output->type != input->type || output->size != input->size) 1202 { 1203 infoLog.append("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str()); 1204 1205 return false; 1206 } 1207 1208 output->reg = input->reg; 1209 output->col = input->col; 1210 1211 matched = true; 1212 break; 1213 } 1214 } 1215 1216 if (!matched) 1217 { 1218 infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str()); 1219 1220 return false; 1221 } 1222 } 1223 1224 mUsesPointSize = vertexShader->mUsesPointSize; 1225 std::string varyingSemantic = (mUsesPointSize && shaderModel == 3) ? "COLOR" : "TEXCOORD"; 1226 std::string targetSemantic = (shaderModel >= 4) ? "SV_Target" : "COLOR"; 1227 std::string positionSemantic = (shaderModel >= 4) ? "SV_Position" : "POSITION"; 1228 std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH"; 1229 1230 // special varyings that use reserved registers 1231 int reservedRegisterIndex = registers; 1232 std::string fragCoordSemantic; 1233 std::string pointCoordSemantic; 1234 1235 if (fragmentShader->mUsesFragCoord) 1236 { 1237 fragCoordSemantic = varyingSemantic + str(reservedRegisterIndex++); 1238 } 1239 1240 if (fragmentShader->mUsesPointCoord) 1241 { 1242 // Shader model 3 uses a special TEXCOORD semantic for point sprite texcoords. 1243 // In DX11 we compute this in the GS. 1244 if (shaderModel == 3) 1245 { 1246 pointCoordSemantic = "TEXCOORD0"; 1247 } 1248 else if (shaderModel >= 4) 1249 { 1250 pointCoordSemantic = varyingSemantic + str(reservedRegisterIndex++); 1251 } 1252 } 1253 1254 vertexHLSL += "struct VS_INPUT\n" 1255 "{\n"; 1256 1257 int semanticIndex = 0; 1258 for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++) 1259 { 1260 switch (attribute->type) 1261 { 1262 case GL_FLOAT: vertexHLSL += " float "; break; 1263 case GL_FLOAT_VEC2: vertexHLSL += " float2 "; break; 1264 case GL_FLOAT_VEC3: vertexHLSL += " float3 "; break; 1265 case GL_FLOAT_VEC4: vertexHLSL += " float4 "; break; 1266 case GL_FLOAT_MAT2: vertexHLSL += " float2x2 "; break; 1267 case GL_FLOAT_MAT3: vertexHLSL += " float3x3 "; break; 1268 case GL_FLOAT_MAT4: vertexHLSL += " float4x4 "; break; 1269 default: UNREACHABLE(); 1270 } 1271 1272 vertexHLSL += decorateAttribute(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n"; 1273 1274 semanticIndex += VariableRowCount(attribute->type); 1275 } 1276 1277 vertexHLSL += "};\n" 1278 "\n" 1279 "struct VS_OUTPUT\n" 1280 "{\n"; 1281 1282 if (shaderModel < 4) 1283 { 1284 vertexHLSL += " float4 gl_Position : " + positionSemantic + ";\n"; 1285 } 1286 1287 for (int r = 0; r < registers; r++) 1288 { 1289 int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1)); 1290 1291 vertexHLSL += " float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n"; 1292 } 1293 1294 if (fragmentShader->mUsesFragCoord) 1295 { 1296 vertexHLSL += " float4 gl_FragCoord : " + fragCoordSemantic + ";\n"; 1297 } 1298 1299 if (vertexShader->mUsesPointSize && shaderModel >= 3) 1300 { 1301 vertexHLSL += " float gl_PointSize : PSIZE;\n"; 1302 } 1303 1304 if (shaderModel >= 4) 1305 { 1306 vertexHLSL += " float4 gl_Position : " + positionSemantic + ";\n"; 1307 } 1308 1309 vertexHLSL += "};\n" 1310 "\n" 1311 "VS_OUTPUT main(VS_INPUT input)\n" 1312 "{\n"; 1313 1314 for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++) 1315 { 1316 vertexHLSL += " " + decorateAttribute(attribute->name) + " = "; 1317 1318 if (VariableRowCount(attribute->type) > 1) // Matrix 1319 { 1320 vertexHLSL += "transpose"; 1321 } 1322 1323 vertexHLSL += "(input." + decorateAttribute(attribute->name) + ");\n"; 1324 } 1325 1326 if (shaderModel >= 4) 1327 { 1328 vertexHLSL += "\n" 1329 " gl_main();\n" 1330 "\n" 1331 " VS_OUTPUT output;\n" 1332 " output.gl_Position.x = gl_Position.x;\n" 1333 " output.gl_Position.y = -gl_Position.y;\n" 1334 " output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" 1335 " output.gl_Position.w = gl_Position.w;\n"; 1336 } 1337 else 1338 { 1339 vertexHLSL += "\n" 1340 " gl_main();\n" 1341 "\n" 1342 " VS_OUTPUT output;\n" 1343 " output.gl_Position.x = gl_Position.x * dx_ViewAdjust.z + dx_ViewAdjust.x * gl_Position.w;\n" 1344 " output.gl_Position.y = -(gl_Position.y * dx_ViewAdjust.w + dx_ViewAdjust.y * gl_Position.w);\n" 1345 " output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" 1346 " output.gl_Position.w = gl_Position.w;\n"; 1347 } 1348 1349 if (vertexShader->mUsesPointSize && shaderModel >= 3) 1350 { 1351 vertexHLSL += " output.gl_PointSize = gl_PointSize;\n"; 1352 } 1353 1354 if (fragmentShader->mUsesFragCoord) 1355 { 1356 vertexHLSL += " output.gl_FragCoord = gl_Position;\n"; 1357 } 1358 1359 for (VaryingList::iterator varying = vertexShader->mVaryings.begin(); varying != vertexShader->mVaryings.end(); varying++) 1360 { 1361 if (varying->reg >= 0) 1362 { 1363 for (int i = 0; i < varying->size; i++) 1364 { 1365 int rows = VariableRowCount(varying->type); 1366 1367 for (int j = 0; j < rows; j++) 1368 { 1369 int r = varying->reg + i * rows + j; 1370 vertexHLSL += " output.v" + str(r); 1371 1372 bool sharedRegister = false; // Register used by multiple varyings 1373 1374 for (int x = 0; x < 4; x++) 1375 { 1376 if (packing[r][x] && packing[r][x] != packing[r][0]) 1377 { 1378 sharedRegister = true; 1379 break; 1380 } 1381 } 1382 1383 if(sharedRegister) 1384 { 1385 vertexHLSL += "."; 1386 1387 for (int x = 0; x < 4; x++) 1388 { 1389 if (packing[r][x] == &*varying) 1390 { 1391 switch(x) 1392 { 1393 case 0: vertexHLSL += "x"; break; 1394 case 1: vertexHLSL += "y"; break; 1395 case 2: vertexHLSL += "z"; break; 1396 case 3: vertexHLSL += "w"; break; 1397 } 1398 } 1399 } 1400 } 1401 1402 vertexHLSL += " = " + varying->name; 1403 1404 if (varying->array) 1405 { 1406 vertexHLSL += "[" + str(i) + "]"; 1407 } 1408 1409 if (rows > 1) 1410 { 1411 vertexHLSL += "[" + str(j) + "]"; 1412 } 1413 1414 vertexHLSL += ";\n"; 1415 } 1416 } 1417 } 1418 } 1419 1420 vertexHLSL += "\n" 1421 " return output;\n" 1422 "}\n"; 1423 1424 pixelHLSL += "struct PS_INPUT\n" 1425 "{\n"; 1426 1427 for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++) 1428 { 1429 if (varying->reg >= 0) 1430 { 1431 for (int i = 0; i < varying->size; i++) 1432 { 1433 int rows = VariableRowCount(varying->type); 1434 for (int j = 0; j < rows; j++) 1435 { 1436 std::string n = str(varying->reg + i * rows + j); 1437 pixelHLSL += " float" + str(VariableColumnCount(varying->type)) + " v" + n + " : " + varyingSemantic + n + ";\n"; 1438 } 1439 } 1440 } 1441 else UNREACHABLE(); 1442 } 1443 1444 if (fragmentShader->mUsesFragCoord) 1445 { 1446 pixelHLSL += " float4 gl_FragCoord : " + fragCoordSemantic + ";\n"; 1447 } 1448 1449 if (fragmentShader->mUsesPointCoord && shaderModel >= 3) 1450 { 1451 pixelHLSL += " float2 gl_PointCoord : " + pointCoordSemantic + ";\n"; 1452 } 1453 1454 // Must consume the PSIZE element if the geometry shader is not active 1455 // We won't know if we use a GS until we draw 1456 if (vertexShader->mUsesPointSize && shaderModel >= 4) 1457 { 1458 pixelHLSL += " float gl_PointSize : PSIZE;\n"; 1459 } 1460 1461 if (fragmentShader->mUsesFragCoord) 1462 { 1463 if (shaderModel >= 4) 1464 { 1465 pixelHLSL += " float4 dx_VPos : SV_Position;\n"; 1466 } 1467 else if (shaderModel >= 3) 1468 { 1469 pixelHLSL += " float2 dx_VPos : VPOS;\n"; 1470 } 1471 } 1472 1473 pixelHLSL += "};\n" 1474 "\n" 1475 "struct PS_OUTPUT\n" 1476 "{\n"; 1477 1478 for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++) 1479 { 1480 pixelHLSL += " float4 gl_Color" + str(renderTargetIndex) + " : " + targetSemantic + str(renderTargetIndex) + ";\n"; 1481 } 1482 1483 if (fragmentShader->mUsesFragDepth) 1484 { 1485 pixelHLSL += " float gl_Depth : " + depthSemantic + ";\n"; 1486 } 1487 1488 pixelHLSL += "};\n" 1489 "\n"; 1490 1491 if (fragmentShader->mUsesFrontFacing) 1492 { 1493 if (shaderModel >= 4) 1494 { 1495 pixelHLSL += "PS_OUTPUT main(PS_INPUT input, bool isFrontFace : SV_IsFrontFace)\n" 1496 "{\n"; 1497 } 1498 else 1499 { 1500 pixelHLSL += "PS_OUTPUT main(PS_INPUT input, float vFace : VFACE)\n" 1501 "{\n"; 1502 } 1503 } 1504 else 1505 { 1506 pixelHLSL += "PS_OUTPUT main(PS_INPUT input)\n" 1507 "{\n"; 1508 } 1509 1510 if (fragmentShader->mUsesFragCoord) 1511 { 1512 pixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n"; 1513 1514 if (shaderModel >= 4) 1515 { 1516 pixelHLSL += " gl_FragCoord.x = input.dx_VPos.x;\n" 1517 " gl_FragCoord.y = input.dx_VPos.y;\n"; 1518 } 1519 else if (shaderModel >= 3) 1520 { 1521 pixelHLSL += " gl_FragCoord.x = input.dx_VPos.x + 0.5;\n" 1522 " gl_FragCoord.y = input.dx_VPos.y + 0.5;\n"; 1523 } 1524 else 1525 { 1526 // dx_ViewCoords contains the viewport width/2, height/2, center.x and center.y. See Renderer::setViewport() 1527 pixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_ViewCoords.x + dx_ViewCoords.z;\n" 1528 " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_ViewCoords.y + dx_ViewCoords.w;\n"; 1529 } 1530 1531 pixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_DepthFront.x + dx_DepthFront.y;\n" 1532 " gl_FragCoord.w = rhw;\n"; 1533 } 1534 1535 if (fragmentShader->mUsesPointCoord && shaderModel >= 3) 1536 { 1537 pixelHLSL += " gl_PointCoord.x = input.gl_PointCoord.x;\n"; 1538 pixelHLSL += " gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n"; 1539 } 1540 1541 if (fragmentShader->mUsesFrontFacing) 1542 { 1543 if (shaderModel <= 3) 1544 { 1545 pixelHLSL += " gl_FrontFacing = (vFace * dx_DepthFront.z >= 0.0);\n"; 1546 } 1547 else 1548 { 1549 pixelHLSL += " gl_FrontFacing = isFrontFace;\n"; 1550 } 1551 } 1552 1553 for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++) 1554 { 1555 if (varying->reg >= 0) 1556 { 1557 for (int i = 0; i < varying->size; i++) 1558 { 1559 int rows = VariableRowCount(varying->type); 1560 for (int j = 0; j < rows; j++) 1561 { 1562 std::string n = str(varying->reg + i * rows + j); 1563 pixelHLSL += " " + varying->name; 1564 1565 if (varying->array) 1566 { 1567 pixelHLSL += "[" + str(i) + "]"; 1568 } 1569 1570 if (rows > 1) 1571 { 1572 pixelHLSL += "[" + str(j) + "]"; 1573 } 1574 1575 switch (VariableColumnCount(varying->type)) 1576 { 1577 case 1: pixelHLSL += " = input.v" + n + ".x;\n"; break; 1578 case 2: pixelHLSL += " = input.v" + n + ".xy;\n"; break; 1579 case 3: pixelHLSL += " = input.v" + n + ".xyz;\n"; break; 1580 case 4: pixelHLSL += " = input.v" + n + ";\n"; break; 1581 default: UNREACHABLE(); 1582 } 1583 } 1584 } 1585 } 1586 else UNREACHABLE(); 1587 } 1588 1589 pixelHLSL += "\n" 1590 " gl_main();\n" 1591 "\n" 1592 " PS_OUTPUT output;\n"; 1593 1594 for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++) 1595 { 1596 unsigned int sourceColorIndex = broadcast ? 0 : renderTargetIndex; 1597 1598 pixelHLSL += " output.gl_Color" + str(renderTargetIndex) + " = gl_Color[" + str(sourceColorIndex) + "];\n"; 1599 } 1600 1601 if (fragmentShader->mUsesFragDepth) 1602 { 1603 pixelHLSL += " output.gl_Depth = gl_Depth;\n"; 1604 } 1605 1606 pixelHLSL += "\n" 1607 " return output;\n" 1608 "}\n"; 1609 1610 return true; 1611 } 1612 1613 bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length) 1614 { 1615 BinaryInputStream stream(binary, length); 1616 1617 int format = 0; 1618 stream.read(&format); 1619 if (format != GL_PROGRAM_BINARY_ANGLE) 1620 { 1621 infoLog.append("Invalid program binary format."); 1622 return false; 1623 } 1624 1625 int version = 0; 1626 stream.read(&version); 1627 if (version != VERSION_DWORD) 1628 { 1629 infoLog.append("Invalid program binary version."); 1630 return false; 1631 } 1632 1633 int compileFlags = 0; 1634 stream.read(&compileFlags); 1635 if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL) 1636 { 1637 infoLog.append("Mismatched compilation flags."); 1638 return false; 1639 } 1640 1641 for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i) 1642 { 1643 stream.read(&mLinkedAttribute[i].type); 1644 std::string name; 1645 stream.read(&name); 1646 mLinkedAttribute[i].name = name; 1647 stream.read(&mSemanticIndex[i]); 1648 } 1649 1650 for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i) 1651 { 1652 stream.read(&mSamplersPS[i].active); 1653 stream.read(&mSamplersPS[i].logicalTextureUnit); 1654 1655 int textureType; 1656 stream.read(&textureType); 1657 mSamplersPS[i].textureType = (TextureType) textureType; 1658 } 1659 1660 for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i) 1661 { 1662 stream.read(&mSamplersVS[i].active); 1663 stream.read(&mSamplersVS[i].logicalTextureUnit); 1664 1665 int textureType; 1666 stream.read(&textureType); 1667 mSamplersVS[i].textureType = (TextureType) textureType; 1668 } 1669 1670 stream.read(&mUsedVertexSamplerRange); 1671 stream.read(&mUsedPixelSamplerRange); 1672 stream.read(&mUsesPointSize); 1673 1674 size_t size; 1675 stream.read(&size); 1676 if (stream.error()) 1677 { 1678 infoLog.append("Invalid program binary."); 1679 return false; 1680 } 1681 1682 mUniforms.resize(size); 1683 for (unsigned int i = 0; i < size; ++i) 1684 { 1685 GLenum type; 1686 GLenum precision; 1687 std::string name; 1688 unsigned int arraySize; 1689 1690 stream.read(&type); 1691 stream.read(&precision); 1692 stream.read(&name); 1693 stream.read(&arraySize); 1694 1695 mUniforms[i] = new Uniform(type, precision, name, arraySize); 1696 1697 stream.read(&mUniforms[i]->psRegisterIndex); 1698 stream.read(&mUniforms[i]->vsRegisterIndex); 1699 stream.read(&mUniforms[i]->registerCount); 1700 } 1701 1702 stream.read(&size); 1703 if (stream.error()) 1704 { 1705 infoLog.append("Invalid program binary."); 1706 return false; 1707 } 1708 1709 mUniformIndex.resize(size); 1710 for (unsigned int i = 0; i < size; ++i) 1711 { 1712 stream.read(&mUniformIndex[i].name); 1713 stream.read(&mUniformIndex[i].element); 1714 stream.read(&mUniformIndex[i].index); 1715 } 1716 1717 unsigned int pixelShaderSize; 1718 stream.read(&pixelShaderSize); 1719 1720 unsigned int vertexShaderSize; 1721 stream.read(&vertexShaderSize); 1722 1723 unsigned int geometryShaderSize; 1724 stream.read(&geometryShaderSize); 1725 1726 const char *ptr = (const char*) binary + stream.offset(); 1727 1728 const GUID *binaryIdentifier = (const GUID *) ptr; 1729 ptr += sizeof(GUID); 1730 1731 GUID identifier = mRenderer->getAdapterIdentifier(); 1732 if (memcmp(&identifier, binaryIdentifier, sizeof(GUID)) != 0) 1733 { 1734 infoLog.append("Invalid program binary."); 1735 return false; 1736 } 1737 1738 const char *pixelShaderFunction = ptr; 1739 ptr += pixelShaderSize; 1740 1741 const char *vertexShaderFunction = ptr; 1742 ptr += vertexShaderSize; 1743 1744 const char *geometryShaderFunction = geometryShaderSize > 0 ? ptr : NULL; 1745 ptr += geometryShaderSize; 1746 1747 mPixelExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(pixelShaderFunction), 1748 pixelShaderSize, rx::SHADER_PIXEL); 1749 if (!mPixelExecutable) 1750 { 1751 infoLog.append("Could not create pixel shader."); 1752 return false; 1753 } 1754 1755 mVertexExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction), 1756 vertexShaderSize, rx::SHADER_VERTEX); 1757 if (!mVertexExecutable) 1758 { 1759 infoLog.append("Could not create vertex shader."); 1760 delete mPixelExecutable; 1761 mPixelExecutable = NULL; 1762 return false; 1763 } 1764 1765 if (geometryShaderFunction != NULL && geometryShaderSize > 0) 1766 { 1767 mGeometryExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction), 1768 geometryShaderSize, rx::SHADER_GEOMETRY); 1769 if (!mGeometryExecutable) 1770 { 1771 infoLog.append("Could not create geometry shader."); 1772 delete mPixelExecutable; 1773 mPixelExecutable = NULL; 1774 delete mVertexExecutable; 1775 mVertexExecutable = NULL; 1776 return false; 1777 } 1778 } 1779 else 1780 { 1781 mGeometryExecutable = NULL; 1782 } 1783 1784 return true; 1785 } 1786 1787 bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length) 1788 { 1789 BinaryOutputStream stream; 1790 1791 stream.write(GL_PROGRAM_BINARY_ANGLE); 1792 stream.write(VERSION_DWORD); 1793 stream.write(ANGLE_COMPILE_OPTIMIZATION_LEVEL); 1794 1795 for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i) 1796 { 1797 stream.write(mLinkedAttribute[i].type); 1798 stream.write(mLinkedAttribute[i].name); 1799 stream.write(mSemanticIndex[i]); 1800 } 1801 1802 for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i) 1803 { 1804 stream.write(mSamplersPS[i].active); 1805 stream.write(mSamplersPS[i].logicalTextureUnit); 1806 stream.write((int) mSamplersPS[i].textureType); 1807 } 1808 1809 for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i) 1810 { 1811 stream.write(mSamplersVS[i].active); 1812 stream.write(mSamplersVS[i].logicalTextureUnit); 1813 stream.write((int) mSamplersVS[i].textureType); 1814 } 1815 1816 stream.write(mUsedVertexSamplerRange); 1817 stream.write(mUsedPixelSamplerRange); 1818 stream.write(mUsesPointSize); 1819 1820 stream.write(mUniforms.size()); 1821 for (unsigned int i = 0; i < mUniforms.size(); ++i) 1822 { 1823 stream.write(mUniforms[i]->type); 1824 stream.write(mUniforms[i]->precision); 1825 stream.write(mUniforms[i]->name); 1826 stream.write(mUniforms[i]->arraySize); 1827 1828 stream.write(mUniforms[i]->psRegisterIndex); 1829 stream.write(mUniforms[i]->vsRegisterIndex); 1830 stream.write(mUniforms[i]->registerCount); 1831 } 1832 1833 stream.write(mUniformIndex.size()); 1834 for (unsigned int i = 0; i < mUniformIndex.size(); ++i) 1835 { 1836 stream.write(mUniformIndex[i].name); 1837 stream.write(mUniformIndex[i].element); 1838 stream.write(mUniformIndex[i].index); 1839 } 1840 1841 UINT pixelShaderSize = mPixelExecutable->getLength(); 1842 stream.write(pixelShaderSize); 1843 1844 UINT vertexShaderSize = mVertexExecutable->getLength(); 1845 stream.write(vertexShaderSize); 1846 1847 UINT geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0; 1848 stream.write(geometryShaderSize); 1849 1850 GUID identifier = mRenderer->getAdapterIdentifier(); 1851 1852 GLsizei streamLength = stream.length(); 1853 const void *streamData = stream.data(); 1854 1855 GLsizei totalLength = streamLength + sizeof(GUID) + pixelShaderSize + vertexShaderSize + geometryShaderSize; 1856 if (totalLength > bufSize) 1857 { 1858 if (length) 1859 { 1860 *length = 0; 1861 } 1862 1863 return false; 1864 } 1865 1866 if (binary) 1867 { 1868 char *ptr = (char*) binary; 1869 1870 memcpy(ptr, streamData, streamLength); 1871 ptr += streamLength; 1872 1873 memcpy(ptr, &identifier, sizeof(GUID)); 1874 ptr += sizeof(GUID); 1875 1876 memcpy(ptr, mPixelExecutable->getFunction(), pixelShaderSize); 1877 ptr += pixelShaderSize; 1878 1879 memcpy(ptr, mVertexExecutable->getFunction(), vertexShaderSize); 1880 ptr += vertexShaderSize; 1881 1882 if (mGeometryExecutable != NULL && geometryShaderSize > 0) 1883 { 1884 memcpy(ptr, mGeometryExecutable->getFunction(), geometryShaderSize); 1885 ptr += geometryShaderSize; 1886 } 1887 1888 ASSERT(ptr - totalLength == binary); 1889 } 1890 1891 if (length) 1892 { 1893 *length = totalLength; 1894 } 1895 1896 return true; 1897 } 1898 1899 GLint ProgramBinary::getLength() 1900 { 1901 GLint length; 1902 if (save(NULL, INT_MAX, &length)) 1903 { 1904 return length; 1905 } 1906 else 1907 { 1908 return 0; 1909 } 1910 } 1911 1912 bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader) 1913 { 1914 if (!fragmentShader || !fragmentShader->isCompiled()) 1915 { 1916 return false; 1917 } 1918 1919 if (!vertexShader || !vertexShader->isCompiled()) 1920 { 1921 return false; 1922 } 1923 1924 std::string pixelHLSL = fragmentShader->getHLSL(); 1925 std::string vertexHLSL = vertexShader->getHLSL(); 1926 1927 // Map the varyings to the register file 1928 const Varying *packing[IMPLEMENTATION_MAX_VARYING_VECTORS][4] = {NULL}; 1929 int registers = packVaryings(infoLog, packing, fragmentShader); 1930 1931 if (registers < 0) 1932 { 1933 return false; 1934 } 1935 1936 if (!linkVaryings(infoLog, registers, packing, pixelHLSL, vertexHLSL, fragmentShader, vertexShader)) 1937 { 1938 return false; 1939 } 1940 1941 bool success = true; 1942 1943 if (!linkAttributes(infoLog, attributeBindings, fragmentShader, vertexShader)) 1944 { 1945 success = false; 1946 } 1947 1948 if (!linkUniforms(infoLog, vertexShader->getUniforms(), fragmentShader->getUniforms())) 1949 { 1950 success = false; 1951 } 1952 1953 // special case for gl_DepthRange, the only built-in uniform (also a struct) 1954 if (vertexShader->mUsesDepthRange || fragmentShader->mUsesDepthRange) 1955 { 1956 mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0)); 1957 mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0)); 1958 mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0)); 1959 } 1960 1961 if (success) 1962 { 1963 mVertexExecutable = mRenderer->compileToExecutable(infoLog, vertexHLSL.c_str(), rx::SHADER_VERTEX); 1964 mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL); 1965 1966 if (usesGeometryShader()) 1967 { 1968 std::string geometryHLSL = generateGeometryShaderHLSL(registers, packing, fragmentShader, vertexShader); 1969 mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(), rx::SHADER_GEOMETRY); 1970 } 1971 1972 if (!mVertexExecutable || !mPixelExecutable || (usesGeometryShader() && !mGeometryExecutable)) 1973 { 1974 infoLog.append("Failed to create D3D shaders."); 1975 success = false; 1976 1977 delete mVertexExecutable; 1978 mVertexExecutable = NULL; 1979 delete mPixelExecutable; 1980 mPixelExecutable = NULL; 1981 delete mGeometryExecutable; 1982 mGeometryExecutable = NULL; 1983 } 1984 } 1985 1986 return success; 1987 } 1988 1989 // Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices 1990 bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader) 1991 { 1992 unsigned int usedLocations = 0; 1993 1994 // Link attributes that have a binding location 1995 for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++) 1996 { 1997 int location = attributeBindings.getAttributeBinding(attribute->name); 1998 1999 if (location != -1) // Set by glBindAttribLocation 2000 { 2001 if (!mLinkedAttribute[location].name.empty()) 2002 { 2003 // Multiple active attributes bound to the same location; not an error 2004 } 2005 2006 mLinkedAttribute[location] = *attribute; 2007 2008 int rows = VariableRowCount(attribute->type); 2009 2010 if (rows + location > MAX_VERTEX_ATTRIBS) 2011 { 2012 infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location); 2013 2014 return false; 2015 } 2016 2017 for (int i = 0; i < rows; i++) 2018 { 2019 usedLocations |= 1 << (location + i); 2020 } 2021 } 2022 } 2023 2024 // Link attributes that don't have a binding location 2025 for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++) 2026 { 2027 int location = attributeBindings.getAttributeBinding(attribute->name); 2028 2029 if (location == -1) // Not set by glBindAttribLocation 2030 { 2031 int rows = VariableRowCount(attribute->type); 2032 int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS); 2033 2034 if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS) 2035 { 2036 infoLog.append("Too many active attributes (%s)", attribute->name.c_str()); 2037 2038 return false; // Fail to link 2039 } 2040 2041 mLinkedAttribute[availableIndex] = *attribute; 2042 } 2043 } 2044 2045 for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; ) 2046 { 2047 int index = vertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name); 2048 int rows = std::max(VariableRowCount(mLinkedAttribute[attributeIndex].type), 1); 2049 2050 for (int r = 0; r < rows; r++) 2051 { 2052 mSemanticIndex[attributeIndex++] = index++; 2053 } 2054 } 2055 2056 return true; 2057 } 2058 2059 bool ProgramBinary::linkUniforms(InfoLog &infoLog, const sh::ActiveUniforms &vertexUniforms, const sh::ActiveUniforms &fragmentUniforms) 2060 { 2061 for (sh::ActiveUniforms::const_iterator uniform = vertexUniforms.begin(); uniform != vertexUniforms.end(); uniform++) 2062 { 2063 if (!defineUniform(GL_VERTEX_SHADER, *uniform, infoLog)) 2064 { 2065 return false; 2066 } 2067 } 2068 2069 for (sh::ActiveUniforms::const_iterator uniform = fragmentUniforms.begin(); uniform != fragmentUniforms.end(); uniform++) 2070 { 2071 if (!defineUniform(GL_FRAGMENT_SHADER, *uniform, infoLog)) 2072 { 2073 return false; 2074 } 2075 } 2076 2077 return true; 2078 } 2079 2080 bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant, InfoLog &infoLog) 2081 { 2082 if (constant.type == GL_SAMPLER_2D || 2083 constant.type == GL_SAMPLER_CUBE) 2084 { 2085 unsigned int samplerIndex = constant.registerIndex; 2086 2087 do 2088 { 2089 if (shader == GL_VERTEX_SHADER) 2090 { 2091 if (samplerIndex < mRenderer->getMaxVertexTextureImageUnits()) 2092 { 2093 mSamplersVS[samplerIndex].active = true; 2094 mSamplersVS[samplerIndex].textureType = (constant.type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D; 2095 mSamplersVS[samplerIndex].logicalTextureUnit = 0; 2096 mUsedVertexSamplerRange = std::max(samplerIndex + 1, mUsedVertexSamplerRange); 2097 } 2098 else 2099 { 2100 infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).", mRenderer->getMaxVertexTextureImageUnits()); 2101 return false; 2102 } 2103 } 2104 else if (shader == GL_FRAGMENT_SHADER) 2105 { 2106 if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS) 2107 { 2108 mSamplersPS[samplerIndex].active = true; 2109 mSamplersPS[samplerIndex].textureType = (constant.type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D; 2110 mSamplersPS[samplerIndex].logicalTextureUnit = 0; 2111 mUsedPixelSamplerRange = std::max(samplerIndex + 1, mUsedPixelSamplerRange); 2112 } 2113 else 2114 { 2115 infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS); 2116 return false; 2117 } 2118 } 2119 else UNREACHABLE(); 2120 2121 samplerIndex++; 2122 } 2123 while (samplerIndex < constant.registerIndex + constant.arraySize); 2124 } 2125 2126 Uniform *uniform = NULL; 2127 GLint location = getUniformLocation(constant.name); 2128 2129 if (location >= 0) // Previously defined, type and precision must match 2130 { 2131 uniform = mUniforms[mUniformIndex[location].index]; 2132 2133 if (uniform->type != constant.type) 2134 { 2135 infoLog.append("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str()); 2136 return false; 2137 } 2138 2139 if (uniform->precision != constant.precision) 2140 { 2141 infoLog.append("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str()); 2142 return false; 2143 } 2144 } 2145 else 2146 { 2147 uniform = new Uniform(constant.type, constant.precision, constant.name, constant.arraySize); 2148 } 2149 2150 if (!uniform) 2151 { 2152 return false; 2153 } 2154 2155 if (shader == GL_FRAGMENT_SHADER) 2156 { 2157 uniform->psRegisterIndex = constant.registerIndex; 2158 } 2159 else if (shader == GL_VERTEX_SHADER) 2160 { 2161 uniform->vsRegisterIndex = constant.registerIndex; 2162 } 2163 else UNREACHABLE(); 2164 2165 if (location >= 0) 2166 { 2167 return uniform->type == constant.type; 2168 } 2169 2170 mUniforms.push_back(uniform); 2171 unsigned int uniformIndex = mUniforms.size() - 1; 2172 2173 for (unsigned int i = 0; i < uniform->elementCount(); i++) 2174 { 2175 mUniformIndex.push_back(UniformLocation(constant.name, i, uniformIndex)); 2176 } 2177 2178 if (shader == GL_VERTEX_SHADER) 2179 { 2180 if (constant.registerIndex + uniform->registerCount > mRenderer->getReservedVertexUniformVectors() + mRenderer->getMaxVertexUniformVectors()) 2181 { 2182 infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)", mRenderer->getMaxVertexUniformVectors()); 2183 return false; 2184 } 2185 } 2186 else if (shader == GL_FRAGMENT_SHADER) 2187 { 2188 if (constant.registerIndex + uniform->registerCount > mRenderer->getReservedFragmentUniformVectors() + mRenderer->getMaxFragmentUniformVectors()) 2189 { 2190 infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)", mRenderer->getMaxFragmentUniformVectors()); 2191 return false; 2192 } 2193 } 2194 else UNREACHABLE(); 2195 2196 return true; 2197 } 2198 2199 std::string ProgramBinary::generateGeometryShaderHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const 2200 { 2201 // for now we only handle point sprite emulation 2202 ASSERT(usesPointSpriteEmulation()); 2203 return generatePointSpriteHLSL(registers, packing, fragmentShader, vertexShader); 2204 } 2205 2206 std::string ProgramBinary::generatePointSpriteHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const 2207 { 2208 ASSERT(registers >= 0); 2209 ASSERT(vertexShader->mUsesPointSize); 2210 ASSERT(mRenderer->getMajorShaderModel() >= 4); 2211 2212 std::string geomHLSL; 2213 2214 std::string varyingSemantic = "TEXCOORD"; 2215 2216 std::string fragCoordSemantic; 2217 std::string pointCoordSemantic; 2218 2219 int reservedRegisterIndex = registers; 2220 2221 if (fragmentShader->mUsesFragCoord) 2222 { 2223 fragCoordSemantic = varyingSemantic + str(reservedRegisterIndex++); 2224 } 2225 2226 if (fragmentShader->mUsesPointCoord) 2227 { 2228 pointCoordSemantic = varyingSemantic + str(reservedRegisterIndex++); 2229 } 2230 2231 geomHLSL += "uniform float4 dx_ViewCoords : register(c1);\n" 2232 "\n" 2233 "struct GS_INPUT\n" 2234 "{\n"; 2235 2236 for (int r = 0; r < registers; r++) 2237 { 2238 int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1)); 2239 2240 geomHLSL += " float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n"; 2241 } 2242 2243 if (fragmentShader->mUsesFragCoord) 2244 { 2245 geomHLSL += " float4 gl_FragCoord : " + fragCoordSemantic + ";\n"; 2246 } 2247 2248 geomHLSL += " float gl_PointSize : PSIZE;\n" 2249 " float4 gl_Position : SV_Position;\n" 2250 "};\n" 2251 "\n" 2252 "struct GS_OUTPUT\n" 2253 "{\n"; 2254 2255 for (int r = 0; r < registers; r++) 2256 { 2257 int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1)); 2258 2259 geomHLSL += " float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n"; 2260 } 2261 2262 if (fragmentShader->mUsesFragCoord) 2263 { 2264 geomHLSL += " float4 gl_FragCoord : " + fragCoordSemantic + ";\n"; 2265 } 2266 2267 if (fragmentShader->mUsesPointCoord) 2268 { 2269 geomHLSL += " float2 gl_PointCoord : " + pointCoordSemantic + ";\n"; 2270 } 2271 2272 geomHLSL += " float gl_PointSize : PSIZE;\n" 2273 " float4 gl_Position : SV_Position;\n" 2274 "};\n" 2275 "\n" 2276 "static float2 pointSpriteCorners[] = \n" 2277 "{\n" 2278 " float2( 0.5f, -0.5f),\n" 2279 " float2( 0.5f, 0.5f),\n" 2280 " float2(-0.5f, -0.5f),\n" 2281 " float2(-0.5f, 0.5f)\n" 2282 "};\n" 2283 "\n" 2284 "static float2 pointSpriteTexcoords[] = \n" 2285 "{\n" 2286 " float2(1.0f, 1.0f),\n" 2287 " float2(1.0f, 0.0f),\n" 2288 " float2(0.0f, 1.0f),\n" 2289 " float2(0.0f, 0.0f)\n" 2290 "};\n" 2291 "\n" 2292 "static float minPointSize = " + str(ALIASED_POINT_SIZE_RANGE_MIN) + ".0f;\n" 2293 "static float maxPointSize = " + str(mRenderer->getMaxPointSize()) + ".0f;\n" 2294 "\n" 2295 "[maxvertexcount(4)]\n" 2296 "void main(point GS_INPUT input[1], inout TriangleStream<GS_OUTPUT> outStream)\n" 2297 "{\n" 2298 " GS_OUTPUT output = (GS_OUTPUT)0;\n" 2299 " output.gl_PointSize = input[0].gl_PointSize;\n"; 2300 2301 for (int r = 0; r < registers; r++) 2302 { 2303 geomHLSL += " output.v" + str(r) + " = input[0].v" + str(r) + ";\n"; 2304 } 2305 2306 if (fragmentShader->mUsesFragCoord) 2307 { 2308 geomHLSL += " output.gl_FragCoord = input[0].gl_FragCoord;\n"; 2309 } 2310 2311 geomHLSL += " \n" 2312 " float gl_PointSize = clamp(input[0].gl_PointSize, minPointSize, maxPointSize);\n" 2313 " float4 gl_Position = input[0].gl_Position;\n" 2314 " float2 viewportScale = float2(1.0f / dx_ViewCoords.x, 1.0f / dx_ViewCoords.y) * gl_Position.w;\n"; 2315 2316 for (int corner = 0; corner < 4; corner++) 2317 { 2318 geomHLSL += " \n" 2319 " output.gl_Position = gl_Position + float4(pointSpriteCorners[" + str(corner) + "] * viewportScale * gl_PointSize, 0.0f, 0.0f);\n"; 2320 2321 if (fragmentShader->mUsesPointCoord) 2322 { 2323 geomHLSL += " output.gl_PointCoord = pointSpriteTexcoords[" + str(corner) + "];\n"; 2324 } 2325 2326 geomHLSL += " outStream.Append(output);\n"; 2327 } 2328 2329 geomHLSL += " \n" 2330 " outStream.RestartStrip();\n" 2331 "}\n"; 2332 2333 return geomHLSL; 2334 } 2335 2336 // This method needs to match OutputHLSL::decorate 2337 std::string ProgramBinary::decorateAttribute(const std::string &name) 2338 { 2339 if (name.compare(0, 3, "gl_") != 0 && name.compare(0, 3, "dx_") != 0) 2340 { 2341 return "_" + name; 2342 } 2343 2344 return name; 2345 } 2346 2347 bool ProgramBinary::isValidated() const 2348 { 2349 return mValidated; 2350 } 2351 2352 void ProgramBinary::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const 2353 { 2354 // Skip over inactive attributes 2355 unsigned int activeAttribute = 0; 2356 unsigned int attribute; 2357 for (attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) 2358 { 2359 if (mLinkedAttribute[attribute].name.empty()) 2360 { 2361 continue; 2362 } 2363 2364 if (activeAttribute == index) 2365 { 2366 break; 2367 } 2368 2369 activeAttribute++; 2370 } 2371 2372 if (bufsize > 0) 2373 { 2374 const char *string = mLinkedAttribute[attribute].name.c_str(); 2375 2376 strncpy(name, string, bufsize); 2377 name[bufsize - 1] = '\0'; 2378 2379 if (length) 2380 { 2381 *length = strlen(name); 2382 } 2383 } 2384 2385 *size = 1; // Always a single 'type' instance 2386 2387 *type = mLinkedAttribute[attribute].type; 2388 } 2389 2390 GLint ProgramBinary::getActiveAttributeCount() const 2391 { 2392 int count = 0; 2393 2394 for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) 2395 { 2396 if (!mLinkedAttribute[attributeIndex].name.empty()) 2397 { 2398 count++; 2399 } 2400 } 2401 2402 return count; 2403 } 2404 2405 GLint ProgramBinary::getActiveAttributeMaxLength() const 2406 { 2407 int maxLength = 0; 2408 2409 for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) 2410 { 2411 if (!mLinkedAttribute[attributeIndex].name.empty()) 2412 { 2413 maxLength = std::max((int)(mLinkedAttribute[attributeIndex].name.length() + 1), maxLength); 2414 } 2415 } 2416 2417 return maxLength; 2418 } 2419 2420 void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const 2421 { 2422 ASSERT(index < mUniforms.size()); // index must be smaller than getActiveUniformCount() 2423 2424 if (bufsize > 0) 2425 { 2426 std::string string = mUniforms[index]->name; 2427 2428 if (mUniforms[index]->isArray()) 2429 { 2430 string += "[0]"; 2431 } 2432 2433 strncpy(name, string.c_str(), bufsize); 2434 name[bufsize - 1] = '\0'; 2435 2436 if (length) 2437 { 2438 *length = strlen(name); 2439 } 2440 } 2441 2442 *size = mUniforms[index]->elementCount(); 2443 2444 *type = mUniforms[index]->type; 2445 } 2446 2447 GLint ProgramBinary::getActiveUniformCount() const 2448 { 2449 return mUniforms.size(); 2450 } 2451 2452 GLint ProgramBinary::getActiveUniformMaxLength() const 2453 { 2454 int maxLength = 0; 2455 2456 unsigned int numUniforms = mUniforms.size(); 2457 for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++) 2458 { 2459 if (!mUniforms[uniformIndex]->name.empty()) 2460 { 2461 int length = (int)(mUniforms[uniformIndex]->name.length() + 1); 2462 if (mUniforms[uniformIndex]->isArray()) 2463 { 2464 length += 3; // Counting in "[0]". 2465 } 2466 maxLength = std::max(length, maxLength); 2467 } 2468 } 2469 2470 return maxLength; 2471 } 2472 2473 void ProgramBinary::validate(InfoLog &infoLog) 2474 { 2475 applyUniforms(); 2476 if (!validateSamplers(&infoLog)) 2477 { 2478 mValidated = false; 2479 } 2480 else 2481 { 2482 mValidated = true; 2483 } 2484 } 2485 2486 bool ProgramBinary::validateSamplers(InfoLog *infoLog) 2487 { 2488 // if any two active samplers in a program are of different types, but refer to the same 2489 // texture image unit, and this is the current program, then ValidateProgram will fail, and 2490 // DrawArrays and DrawElements will issue the INVALID_OPERATION error. 2491 2492 const unsigned int maxCombinedTextureImageUnits = mRenderer->getMaxCombinedTextureImageUnits(); 2493 TextureType textureUnitType[IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS]; 2494 2495 for (unsigned int i = 0; i < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i) 2496 { 2497 textureUnitType[i] = TEXTURE_UNKNOWN; 2498 } 2499 2500 for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i) 2501 { 2502 if (mSamplersPS[i].active) 2503 { 2504 unsigned int unit = mSamplersPS[i].logicalTextureUnit; 2505 2506 if (unit >= maxCombinedTextureImageUnits) 2507 { 2508 if (infoLog) 2509 { 2510 infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits); 2511 } 2512 2513 return false; 2514 } 2515 2516 if (textureUnitType[unit] != TEXTURE_UNKNOWN) 2517 { 2518 if (mSamplersPS[i].textureType != textureUnitType[unit]) 2519 { 2520 if (infoLog) 2521 { 2522 infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit); 2523 } 2524 2525 return false; 2526 } 2527 } 2528 else 2529 { 2530 textureUnitType[unit] = mSamplersPS[i].textureType; 2531 } 2532 } 2533 } 2534 2535 for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i) 2536 { 2537 if (mSamplersVS[i].active) 2538 { 2539 unsigned int unit = mSamplersVS[i].logicalTextureUnit; 2540 2541 if (unit >= maxCombinedTextureImageUnits) 2542 { 2543 if (infoLog) 2544 { 2545 infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits); 2546 } 2547 2548 return false; 2549 } 2550 2551 if (textureUnitType[unit] != TEXTURE_UNKNOWN) 2552 { 2553 if (mSamplersVS[i].textureType != textureUnitType[unit]) 2554 { 2555 if (infoLog) 2556 { 2557 infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit); 2558 } 2559 2560 return false; 2561 } 2562 } 2563 else 2564 { 2565 textureUnitType[unit] = mSamplersVS[i].textureType; 2566 } 2567 } 2568 } 2569 2570 return true; 2571 } 2572 2573 ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(TEXTURE_2D) 2574 { 2575 } 2576 2577 struct AttributeSorter 2578 { 2579 AttributeSorter(const int (&semanticIndices)[MAX_VERTEX_ATTRIBS]) 2580 : originalIndices(semanticIndices) 2581 { 2582 for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 2583 { 2584 indices[i] = i; 2585 } 2586 2587 std::sort(&indices[0], &indices[MAX_VERTEX_ATTRIBS], *this); 2588 } 2589 2590 bool operator()(int a, int b) 2591 { 2592 return originalIndices[a] == -1 ? false : originalIndices[a] < originalIndices[b]; 2593 } 2594 2595 int indices[MAX_VERTEX_ATTRIBS]; 2596 const int (&originalIndices)[MAX_VERTEX_ATTRIBS]; 2597 }; 2598 2599 void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const 2600 { 2601 AttributeSorter sorter(mSemanticIndex); 2602 2603 int oldIndices[MAX_VERTEX_ATTRIBS]; 2604 rx::TranslatedAttribute oldTranslatedAttributes[MAX_VERTEX_ATTRIBS]; 2605 2606 for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 2607 { 2608 oldIndices[i] = mSemanticIndex[i]; 2609 oldTranslatedAttributes[i] = attributes[i]; 2610 } 2611 2612 for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 2613 { 2614 int oldIndex = sorter.indices[i]; 2615 sortedSemanticIndices[i] = oldIndices[oldIndex]; 2616 attributes[i] = oldTranslatedAttributes[oldIndex]; 2617 } 2618 } 2619 2620 } 2621