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