1// 2// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. 3// Use of this source code is governed by a BSD-style license that can be 4// found in the LICENSE file. 5// 6 7// Program.cpp: Implements the gl::Program class. Implements GL program objects 8// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28. 9 10#include "libGLESv2/BinaryStream.h" 11#include "libGLESv2/ProgramBinary.h" 12#include "libGLESv2/Framebuffer.h" 13#include "libGLESv2/FramebufferAttachment.h" 14#include "libGLESv2/Renderbuffer.h" 15#include "libGLESv2/renderer/ShaderExecutable.h" 16 17#include "common/debug.h" 18#include "common/version.h" 19#include "common/utilities.h" 20#include "common/platform.h" 21 22#include "libGLESv2/main.h" 23#include "libGLESv2/Shader.h" 24#include "libGLESv2/Program.h" 25#include "libGLESv2/renderer/ProgramImpl.h" 26#include "libGLESv2/renderer/Renderer.h" 27#include "libGLESv2/renderer/d3d/DynamicHLSL.h" 28#include "libGLESv2/renderer/d3d/ShaderD3D.h" 29#include "libGLESv2/renderer/d3d/VertexDataManager.h" 30#include "libGLESv2/Context.h" 31#include "libGLESv2/Buffer.h" 32#include "common/blocklayout.h" 33 34namespace gl 35{ 36 37namespace 38{ 39 40GLenum GetTextureType(GLenum samplerType) 41{ 42 switch (samplerType) 43 { 44 case GL_SAMPLER_2D: 45 case GL_INT_SAMPLER_2D: 46 case GL_UNSIGNED_INT_SAMPLER_2D: 47 case GL_SAMPLER_2D_SHADOW: 48 return GL_TEXTURE_2D; 49 case GL_SAMPLER_3D: 50 case GL_INT_SAMPLER_3D: 51 case GL_UNSIGNED_INT_SAMPLER_3D: 52 return GL_TEXTURE_3D; 53 case GL_SAMPLER_CUBE: 54 case GL_SAMPLER_CUBE_SHADOW: 55 return GL_TEXTURE_CUBE_MAP; 56 case GL_INT_SAMPLER_CUBE: 57 case GL_UNSIGNED_INT_SAMPLER_CUBE: 58 return GL_TEXTURE_CUBE_MAP; 59 case GL_SAMPLER_2D_ARRAY: 60 case GL_INT_SAMPLER_2D_ARRAY: 61 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 62 case GL_SAMPLER_2D_ARRAY_SHADOW: 63 return GL_TEXTURE_2D_ARRAY; 64 default: UNREACHABLE(); 65 } 66 67 return GL_TEXTURE_2D; 68} 69 70unsigned int ParseAndStripArrayIndex(std::string* name) 71{ 72 unsigned int subscript = GL_INVALID_INDEX; 73 74 // Strip any trailing array operator and retrieve the subscript 75 size_t open = name->find_last_of('['); 76 size_t close = name->find_last_of(']'); 77 if (open != std::string::npos && close == name->length() - 1) 78 { 79 subscript = atoi(name->substr(open + 1).c_str()); 80 name->erase(open); 81 } 82 83 return subscript; 84} 85 86void GetDefaultInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]) 87{ 88 size_t layoutIndex = 0; 89 for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++) 90 { 91 ASSERT(layoutIndex < MAX_VERTEX_ATTRIBS); 92 93 const sh::Attribute &shaderAttr = shaderAttributes[attributeIndex]; 94 95 if (shaderAttr.type != GL_NONE) 96 { 97 GLenum transposedType = TransposeMatrixType(shaderAttr.type); 98 99 for (size_t rowIndex = 0; static_cast<int>(rowIndex) < VariableRowCount(transposedType); rowIndex++, layoutIndex++) 100 { 101 VertexFormat *defaultFormat = &inputLayout[layoutIndex]; 102 103 defaultFormat->mType = VariableComponentType(transposedType); 104 defaultFormat->mNormalized = false; 105 defaultFormat->mPureInteger = (defaultFormat->mType != GL_FLOAT); // note: inputs can not be bool 106 defaultFormat->mComponents = VariableColumnCount(transposedType); 107 } 108 } 109 } 110} 111 112std::vector<GLenum> GetDefaultOutputLayoutFromShader(const std::vector<rx::PixelShaderOutputVariable> &shaderOutputVars) 113{ 114 std::vector<GLenum> defaultPixelOutput(1); 115 116 ASSERT(!shaderOutputVars.empty()); 117 defaultPixelOutput[0] = GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex; 118 119 return defaultPixelOutput; 120} 121 122bool IsRowMajorLayout(const sh::InterfaceBlockField &var) 123{ 124 return var.isRowMajorLayout; 125} 126 127bool IsRowMajorLayout(const sh::ShaderVariable &var) 128{ 129 return false; 130} 131 132} 133 134VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index) 135 : name(name), element(element), index(index) 136{ 137} 138 139ProgramBinary::VertexExecutable::VertexExecutable(const VertexFormat inputLayout[], 140 const GLenum signature[], 141 rx::ShaderExecutable *shaderExecutable) 142 : mShaderExecutable(shaderExecutable) 143{ 144 for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++) 145 { 146 mInputs[attributeIndex] = inputLayout[attributeIndex]; 147 mSignature[attributeIndex] = signature[attributeIndex]; 148 } 149} 150 151ProgramBinary::VertexExecutable::~VertexExecutable() 152{ 153 SafeDelete(mShaderExecutable); 154} 155 156bool ProgramBinary::VertexExecutable::matchesSignature(const GLenum signature[]) const 157{ 158 for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) 159 { 160 if (mSignature[attributeIndex] != signature[attributeIndex]) 161 { 162 return false; 163 } 164 } 165 166 return true; 167} 168 169ProgramBinary::PixelExecutable::PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable) 170 : mOutputSignature(outputSignature), 171 mShaderExecutable(shaderExecutable) 172{ 173} 174 175ProgramBinary::PixelExecutable::~PixelExecutable() 176{ 177 SafeDelete(mShaderExecutable); 178} 179 180LinkedVarying::LinkedVarying() 181{ 182} 183 184LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, const std::string &semanticName, 185 unsigned int semanticIndex, unsigned int semanticIndexCount) 186 : name(name), type(type), size(size), semanticName(semanticName), semanticIndex(semanticIndex), semanticIndexCount(semanticIndexCount) 187{ 188} 189 190unsigned int ProgramBinary::mCurrentSerial = 1; 191 192ProgramBinary::ProgramBinary(rx::ProgramImpl *impl) 193 : RefCountObject(0), 194 mProgram(impl), 195 mGeometryExecutable(NULL), 196 mUsedVertexSamplerRange(0), 197 mUsedPixelSamplerRange(0), 198 mUsesPointSize(false), 199 mShaderVersion(100), 200 mDirtySamplerMapping(true), 201 mValidated(false), 202 mSerial(issueSerial()) 203{ 204 ASSERT(impl); 205 206 for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++) 207 { 208 mSemanticIndex[index] = -1; 209 } 210} 211 212ProgramBinary::~ProgramBinary() 213{ 214 reset(); 215 SafeDelete(mProgram); 216} 217 218unsigned int ProgramBinary::getSerial() const 219{ 220 return mSerial; 221} 222 223int ProgramBinary::getShaderVersion() const 224{ 225 return mShaderVersion; 226} 227 228unsigned int ProgramBinary::issueSerial() 229{ 230 return mCurrentSerial++; 231} 232 233rx::ShaderExecutable *ProgramBinary::getPixelExecutableForFramebuffer(const Framebuffer *fbo) 234{ 235 std::vector<GLenum> outputs; 236 237 const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender(); 238 239 for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) 240 { 241 const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment]; 242 243 if (colorbuffer) 244 { 245 outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding()); 246 } 247 else 248 { 249 outputs.push_back(GL_NONE); 250 } 251 } 252 253 return getPixelExecutableForOutputLayout(outputs); 254} 255 256rx::ShaderExecutable *ProgramBinary::getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputSignature) 257{ 258 for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++) 259 { 260 if (mPixelExecutables[executableIndex]->matchesSignature(outputSignature)) 261 { 262 return mPixelExecutables[executableIndex]->shaderExecutable(); 263 } 264 } 265 266 InfoLog tempInfoLog; 267 rx::ShaderExecutable *pixelExecutable = mProgram->getPixelExecutableForOutputLayout(tempInfoLog, outputSignature, 268 mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); 269 270 if (!pixelExecutable) 271 { 272 std::vector<char> tempCharBuffer(tempInfoLog.getLength() + 3); 273 tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]); 274 ERR("Error compiling dynamic pixel executable:\n%s\n", &tempCharBuffer[0]); 275 } 276 else 277 { 278 mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable)); 279 } 280 281 return pixelExecutable; 282} 283 284rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]) 285{ 286 GLenum signature[MAX_VERTEX_ATTRIBS]; 287 mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature); 288 289 for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++) 290 { 291 if (mVertexExecutables[executableIndex]->matchesSignature(signature)) 292 { 293 return mVertexExecutables[executableIndex]->shaderExecutable(); 294 } 295 } 296 297 InfoLog tempInfoLog; 298 rx::ShaderExecutable *vertexExecutable = mProgram->getVertexExecutableForInputLayout(tempInfoLog, inputLayout, mShaderAttributes, 299 mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); 300 301 if (!vertexExecutable) 302 { 303 std::vector<char> tempCharBuffer(tempInfoLog.getLength()+3); 304 tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]); 305 ERR("Error compiling dynamic vertex executable:\n%s\n", &tempCharBuffer[0]); 306 } 307 else 308 { 309 mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, vertexExecutable)); 310 } 311 312 return vertexExecutable; 313} 314 315rx::ShaderExecutable *ProgramBinary::getGeometryExecutable() const 316{ 317 return mGeometryExecutable; 318} 319 320GLuint ProgramBinary::getAttributeLocation(const char *name) 321{ 322 if (name) 323 { 324 for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++) 325 { 326 if (mLinkedAttribute[index].name == std::string(name)) 327 { 328 return index; 329 } 330 } 331 } 332 333 return -1; 334} 335 336int ProgramBinary::getSemanticIndex(int attributeIndex) 337{ 338 ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS); 339 340 return mSemanticIndex[attributeIndex]; 341} 342 343// Returns one more than the highest sampler index used. 344GLint ProgramBinary::getUsedSamplerRange(SamplerType type) 345{ 346 switch (type) 347 { 348 case SAMPLER_PIXEL: 349 return mUsedPixelSamplerRange; 350 case SAMPLER_VERTEX: 351 return mUsedVertexSamplerRange; 352 default: 353 UNREACHABLE(); 354 return 0; 355 } 356} 357 358bool ProgramBinary::usesPointSize() const 359{ 360 return mUsesPointSize; 361} 362 363bool ProgramBinary::usesPointSpriteEmulation() const 364{ 365 return mUsesPointSize && mProgram->getRenderer()->getMajorShaderModel() >= 4; 366} 367 368bool ProgramBinary::usesGeometryShader() const 369{ 370 return usesPointSpriteEmulation(); 371} 372 373GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps) 374{ 375 GLint logicalTextureUnit = -1; 376 377 switch (type) 378 { 379 case SAMPLER_PIXEL: 380 ASSERT(samplerIndex < caps.maxTextureImageUnits); 381 if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active) 382 { 383 logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit; 384 } 385 break; 386 case SAMPLER_VERTEX: 387 ASSERT(samplerIndex < caps.maxVertexTextureImageUnits); 388 if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active) 389 { 390 logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit; 391 } 392 break; 393 default: UNREACHABLE(); 394 } 395 396 if (logicalTextureUnit >= 0 && logicalTextureUnit < static_cast<GLint>(caps.maxCombinedTextureImageUnits)) 397 { 398 return logicalTextureUnit; 399 } 400 401 return -1; 402} 403 404// Returns the texture type for a given Direct3D 9 sampler type and 405// index (0-15 for the pixel shader and 0-3 for the vertex shader). 406GLenum ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex) 407{ 408 switch (type) 409 { 410 case SAMPLER_PIXEL: 411 ASSERT(samplerIndex < mSamplersPS.size()); 412 ASSERT(mSamplersPS[samplerIndex].active); 413 return mSamplersPS[samplerIndex].textureType; 414 case SAMPLER_VERTEX: 415 ASSERT(samplerIndex < mSamplersVS.size()); 416 ASSERT(mSamplersVS[samplerIndex].active); 417 return mSamplersVS[samplerIndex].textureType; 418 default: UNREACHABLE(); 419 } 420 421 return GL_TEXTURE_2D; 422} 423 424GLint ProgramBinary::getUniformLocation(std::string name) 425{ 426 unsigned int subscript = ParseAndStripArrayIndex(&name); 427 428 unsigned int numUniforms = mUniformIndex.size(); 429 for (unsigned int location = 0; location < numUniforms; location++) 430 { 431 if (mUniformIndex[location].name == name) 432 { 433 const int index = mUniformIndex[location].index; 434 const bool isArray = mUniforms[index]->isArray(); 435 436 if ((isArray && mUniformIndex[location].element == subscript) || 437 (subscript == GL_INVALID_INDEX)) 438 { 439 return location; 440 } 441 } 442 } 443 444 return -1; 445} 446 447GLuint ProgramBinary::getUniformIndex(std::string name) 448{ 449 unsigned int subscript = ParseAndStripArrayIndex(&name); 450 451 // The app is not allowed to specify array indices other than 0 for arrays of basic types 452 if (subscript != 0 && subscript != GL_INVALID_INDEX) 453 { 454 return GL_INVALID_INDEX; 455 } 456 457 unsigned int numUniforms = mUniforms.size(); 458 for (unsigned int index = 0; index < numUniforms; index++) 459 { 460 if (mUniforms[index]->name == name) 461 { 462 if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX) 463 { 464 return index; 465 } 466 } 467 } 468 469 return GL_INVALID_INDEX; 470} 471 472GLuint ProgramBinary::getUniformBlockIndex(std::string name) 473{ 474 unsigned int subscript = ParseAndStripArrayIndex(&name); 475 476 unsigned int numUniformBlocks = mUniformBlocks.size(); 477 for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++) 478 { 479 const UniformBlock &uniformBlock = *mUniformBlocks[blockIndex]; 480 if (uniformBlock.name == name) 481 { 482 const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0); 483 if (subscript == uniformBlock.elementIndex || arrayElementZero) 484 { 485 return blockIndex; 486 } 487 } 488 } 489 490 return GL_INVALID_INDEX; 491} 492 493UniformBlock *ProgramBinary::getUniformBlockByIndex(GLuint blockIndex) 494{ 495 ASSERT(blockIndex < mUniformBlocks.size()); 496 return mUniformBlocks[blockIndex]; 497} 498 499GLint ProgramBinary::getFragDataLocation(const char *name) const 500{ 501 std::string baseName(name); 502 unsigned int arrayIndex; 503 arrayIndex = ParseAndStripArrayIndex(&baseName); 504 505 for (auto locationIt = mOutputVariables.begin(); locationIt != mOutputVariables.end(); locationIt++) 506 { 507 const VariableLocation &outputVariable = locationIt->second; 508 509 if (outputVariable.name == baseName && (arrayIndex == GL_INVALID_INDEX || arrayIndex == outputVariable.element)) 510 { 511 return static_cast<GLint>(locationIt->first); 512 } 513 } 514 515 return -1; 516} 517 518size_t ProgramBinary::getTransformFeedbackVaryingCount() const 519{ 520 return mTransformFeedbackLinkedVaryings.size(); 521} 522 523const LinkedVarying &ProgramBinary::getTransformFeedbackVarying(size_t idx) const 524{ 525 return mTransformFeedbackLinkedVaryings[idx]; 526} 527 528GLenum ProgramBinary::getTransformFeedbackBufferMode() const 529{ 530 return mTransformFeedbackBufferMode; 531} 532 533template <typename T> 534static inline void SetIfDirty(T *dest, const T& source, bool *dirtyFlag) 535{ 536 ASSERT(dest != NULL); 537 ASSERT(dirtyFlag != NULL); 538 539 *dirtyFlag = *dirtyFlag || (memcmp(dest, &source, sizeof(T)) != 0); 540 *dest = source; 541} 542 543template <typename T> 544void ProgramBinary::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType) 545{ 546 const int components = VariableComponentCount(targetUniformType); 547 const GLenum targetBoolType = VariableBoolVectorType(targetUniformType); 548 549 LinkedUniform *targetUniform = getUniformByLocation(location); 550 551 int elementCount = targetUniform->elementCount(); 552 553 count = std::min(elementCount - (int)mUniformIndex[location].element, count); 554 555 if (targetUniform->type == targetUniformType) 556 { 557 T *target = reinterpret_cast<T*>(targetUniform->data) + mUniformIndex[location].element * 4; 558 559 for (int i = 0; i < count; i++) 560 { 561 T *dest = target + (i * 4); 562 const T *source = v + (i * components); 563 564 for (int c = 0; c < components; c++) 565 { 566 SetIfDirty(dest + c, source[c], &targetUniform->dirty); 567 } 568 for (int c = components; c < 4; c++) 569 { 570 SetIfDirty(dest + c, T(0), &targetUniform->dirty); 571 } 572 } 573 } 574 else if (targetUniform->type == targetBoolType) 575 { 576 GLint *boolParams = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4; 577 578 for (int i = 0; i < count; i++) 579 { 580 GLint *dest = boolParams + (i * 4); 581 const T *source = v + (i * components); 582 583 for (int c = 0; c < components; c++) 584 { 585 SetIfDirty(dest + c, (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty); 586 } 587 for (int c = components; c < 4; c++) 588 { 589 SetIfDirty(dest + c, GL_FALSE, &targetUniform->dirty); 590 } 591 } 592 } 593 else if (IsSampler(targetUniform->type)) 594 { 595 ASSERT(targetUniformType == GL_INT); 596 597 GLint *target = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4; 598 599 bool wasDirty = targetUniform->dirty; 600 601 for (int i = 0; i < count; i++) 602 { 603 GLint *dest = target + (i * 4); 604 const GLint *source = reinterpret_cast<const GLint*>(v) + (i * components); 605 606 SetIfDirty(dest + 0, source[0], &targetUniform->dirty); 607 SetIfDirty(dest + 1, 0, &targetUniform->dirty); 608 SetIfDirty(dest + 2, 0, &targetUniform->dirty); 609 SetIfDirty(dest + 3, 0, &targetUniform->dirty); 610 } 611 612 if (!wasDirty && targetUniform->dirty) 613 { 614 mDirtySamplerMapping = true; 615 } 616 } 617 else UNREACHABLE(); 618} 619 620void ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) 621{ 622 setUniform(location, count, v, GL_FLOAT); 623} 624 625void ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) 626{ 627 setUniform(location, count, v, GL_FLOAT_VEC2); 628} 629 630void ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) 631{ 632 setUniform(location, count, v, GL_FLOAT_VEC3); 633} 634 635void ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) 636{ 637 setUniform(location, count, v, GL_FLOAT_VEC4); 638} 639 640template<typename T> 641bool transposeMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight) 642{ 643 bool dirty = false; 644 int copyWidth = std::min(targetHeight, srcWidth); 645 int copyHeight = std::min(targetWidth, srcHeight); 646 647 for (int x = 0; x < copyWidth; x++) 648 { 649 for (int y = 0; y < copyHeight; y++) 650 { 651 SetIfDirty(target + (x * targetWidth + y), static_cast<T>(value[y * srcWidth + x]), &dirty); 652 } 653 } 654 // clear unfilled right side 655 for (int y = 0; y < copyWidth; y++) 656 { 657 for (int x = copyHeight; x < targetWidth; x++) 658 { 659 SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty); 660 } 661 } 662 // clear unfilled bottom. 663 for (int y = copyWidth; y < targetHeight; y++) 664 { 665 for (int x = 0; x < targetWidth; x++) 666 { 667 SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty); 668 } 669 } 670 671 return dirty; 672} 673 674template<typename T> 675bool expandMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight) 676{ 677 bool dirty = false; 678 int copyWidth = std::min(targetWidth, srcWidth); 679 int copyHeight = std::min(targetHeight, srcHeight); 680 681 for (int y = 0; y < copyHeight; y++) 682 { 683 for (int x = 0; x < copyWidth; x++) 684 { 685 SetIfDirty(target + (y * targetWidth + x), static_cast<T>(value[y * srcWidth + x]), &dirty); 686 } 687 } 688 // clear unfilled right side 689 for (int y = 0; y < copyHeight; y++) 690 { 691 for (int x = copyWidth; x < targetWidth; x++) 692 { 693 SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty); 694 } 695 } 696 // clear unfilled bottom. 697 for (int y = copyHeight; y < targetHeight; y++) 698 { 699 for (int x = 0; x < targetWidth; x++) 700 { 701 SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty); 702 } 703 } 704 705 return dirty; 706} 707 708template <int cols, int rows> 709void ProgramBinary::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType) 710{ 711 LinkedUniform *targetUniform = getUniformByLocation(location); 712 713 int elementCount = targetUniform->elementCount(); 714 715 count = std::min(elementCount - (int)mUniformIndex[location].element, count); 716 const unsigned int targetMatrixStride = (4 * rows); 717 GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * targetMatrixStride); 718 719 for (int i = 0; i < count; i++) 720 { 721 // Internally store matrices as transposed versions to accomodate HLSL matrix indexing 722 if (transpose == GL_FALSE) 723 { 724 targetUniform->dirty = transposeMatrix<GLfloat>(target, value, 4, rows, rows, cols) || targetUniform->dirty; 725 } 726 else 727 { 728 targetUniform->dirty = expandMatrix<GLfloat>(target, value, 4, rows, cols, rows) || targetUniform->dirty; 729 } 730 target += targetMatrixStride; 731 value += cols * rows; 732 } 733} 734 735void ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 736{ 737 setUniformMatrixfv<2, 2>(location, count, transpose, value, GL_FLOAT_MAT2); 738} 739 740void ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 741{ 742 setUniformMatrixfv<3, 3>(location, count, transpose, value, GL_FLOAT_MAT3); 743} 744 745void ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 746{ 747 setUniformMatrixfv<4, 4>(location, count, transpose, value, GL_FLOAT_MAT4); 748} 749 750void ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 751{ 752 setUniformMatrixfv<2, 3>(location, count, transpose, value, GL_FLOAT_MAT2x3); 753} 754 755void ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 756{ 757 setUniformMatrixfv<3, 2>(location, count, transpose, value, GL_FLOAT_MAT3x2); 758} 759 760void ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 761{ 762 setUniformMatrixfv<2, 4>(location, count, transpose, value, GL_FLOAT_MAT2x4); 763} 764 765void ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 766{ 767 setUniformMatrixfv<4, 2>(location, count, transpose, value, GL_FLOAT_MAT4x2); 768} 769 770void ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 771{ 772 setUniformMatrixfv<3, 4>(location, count, transpose, value, GL_FLOAT_MAT3x4); 773} 774 775void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) 776{ 777 setUniformMatrixfv<4, 3>(location, count, transpose, value, GL_FLOAT_MAT4x3); 778} 779 780void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) 781{ 782 setUniform(location, count, v, GL_INT); 783} 784 785void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v) 786{ 787 setUniform(location, count, v, GL_INT_VEC2); 788} 789 790void ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v) 791{ 792 setUniform(location, count, v, GL_INT_VEC3); 793} 794 795void ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v) 796{ 797 setUniform(location, count, v, GL_INT_VEC4); 798} 799 800void ProgramBinary::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) 801{ 802 setUniform(location, count, v, GL_UNSIGNED_INT); 803} 804 805void ProgramBinary::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) 806{ 807 setUniform(location, count, v, GL_UNSIGNED_INT_VEC2); 808} 809 810void ProgramBinary::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) 811{ 812 setUniform(location, count, v, GL_UNSIGNED_INT_VEC3); 813} 814 815void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) 816{ 817 setUniform(location, count, v, GL_UNSIGNED_INT_VEC4); 818} 819 820template <typename T> 821void ProgramBinary::getUniformv(GLint location, T *params, GLenum uniformType) 822{ 823 LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index]; 824 825 if (IsMatrixType(targetUniform->type)) 826 { 827 const int rows = VariableRowCount(targetUniform->type); 828 const int cols = VariableColumnCount(targetUniform->type); 829 transposeMatrix(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4 * rows, rows, cols, 4, rows); 830 } 831 else if (uniformType == VariableComponentType(targetUniform->type)) 832 { 833 unsigned int size = VariableComponentCount(targetUniform->type); 834 memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(T), 835 size * sizeof(T)); 836 } 837 else 838 { 839 unsigned int size = VariableComponentCount(targetUniform->type); 840 switch (VariableComponentType(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) ? static_cast<T>(0) : static_cast<T>(1); 849 } 850 } 851 break; 852 853 case GL_FLOAT: 854 { 855 GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; 856 857 for (unsigned int i = 0; i < size; i++) 858 { 859 params[i] = static_cast<T>(floatParams[i]); 860 } 861 } 862 break; 863 864 case GL_INT: 865 { 866 GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; 867 868 for (unsigned int i = 0; i < size; i++) 869 { 870 params[i] = static_cast<T>(intParams[i]); 871 } 872 } 873 break; 874 875 case GL_UNSIGNED_INT: 876 { 877 GLuint *uintParams = (GLuint*)targetUniform->data + mUniformIndex[location].element * 4; 878 879 for (unsigned int i = 0; i < size; i++) 880 { 881 params[i] = static_cast<T>(uintParams[i]); 882 } 883 } 884 break; 885 886 default: UNREACHABLE(); 887 } 888 } 889} 890 891void ProgramBinary::getUniformfv(GLint location, GLfloat *params) 892{ 893 getUniformv(location, params, GL_FLOAT); 894} 895 896void ProgramBinary::getUniformiv(GLint location, GLint *params) 897{ 898 getUniformv(location, params, GL_INT); 899} 900 901void ProgramBinary::getUniformuiv(GLint location, GLuint *params) 902{ 903 getUniformv(location, params, GL_UNSIGNED_INT); 904} 905 906void ProgramBinary::dirtyAllUniforms() 907{ 908 unsigned int numUniforms = mUniforms.size(); 909 for (unsigned int index = 0; index < numUniforms; index++) 910 { 911 mUniforms[index]->dirty = true; 912 } 913} 914 915void ProgramBinary::updateSamplerMapping() 916{ 917 if (!mDirtySamplerMapping) 918 { 919 return; 920 } 921 922 mDirtySamplerMapping = false; 923 924 // Retrieve sampler uniform values 925 for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) 926 { 927 LinkedUniform *targetUniform = mUniforms[uniformIndex]; 928 929 if (targetUniform->dirty) 930 { 931 if (IsSampler(targetUniform->type)) 932 { 933 int count = targetUniform->elementCount(); 934 GLint (*v)[4] = reinterpret_cast<GLint(*)[4]>(targetUniform->data); 935 936 if (targetUniform->isReferencedByFragmentShader()) 937 { 938 unsigned int firstIndex = targetUniform->psRegisterIndex; 939 940 for (int i = 0; i < count; i++) 941 { 942 unsigned int samplerIndex = firstIndex + i; 943 944 if (samplerIndex < mSamplersPS.size()) 945 { 946 ASSERT(mSamplersPS[samplerIndex].active); 947 mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0]; 948 } 949 } 950 } 951 952 if (targetUniform->isReferencedByVertexShader()) 953 { 954 unsigned int firstIndex = targetUniform->vsRegisterIndex; 955 956 for (int i = 0; i < count; i++) 957 { 958 unsigned int samplerIndex = firstIndex + i; 959 960 if (samplerIndex < mSamplersVS.size()) 961 { 962 ASSERT(mSamplersVS[samplerIndex].active); 963 mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0]; 964 } 965 } 966 } 967 } 968 } 969 } 970} 971 972// Applies all the uniforms set for this program object to the renderer 973void ProgramBinary::applyUniforms() 974{ 975 updateSamplerMapping(); 976 977 mProgram->getRenderer()->applyUniforms(*this); 978 979 for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) 980 { 981 mUniforms[uniformIndex]->dirty = false; 982 } 983} 984 985bool ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const Caps &caps) 986{ 987 const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL}; 988 const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL}; 989 990 const unsigned int reservedBuffersInVS = mProgram->getRenderer()->getReservedVertexUniformBuffers(); 991 const unsigned int reservedBuffersInFS = mProgram->getRenderer()->getReservedFragmentUniformBuffers(); 992 993 ASSERT(boundBuffers.size() == mUniformBlocks.size()); 994 995 for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++) 996 { 997 UniformBlock *uniformBlock = getUniformBlockByIndex(uniformBlockIndex); 998 gl::Buffer *uniformBuffer = boundBuffers[uniformBlockIndex]; 999 1000 ASSERT(uniformBlock && uniformBuffer); 1001 1002 if (uniformBuffer->getSize() < uniformBlock->dataSize) 1003 { 1004 // undefined behaviour 1005 return false; 1006 } 1007 1008 // Unnecessary to apply an unreferenced standard or shared UBO 1009 if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader()) 1010 { 1011 continue; 1012 } 1013 1014 if (uniformBlock->isReferencedByVertexShader()) 1015 { 1016 unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS; 1017 ASSERT(vertexUniformBuffers[registerIndex] == NULL); 1018 ASSERT(registerIndex < caps.maxVertexUniformBlocks); 1019 vertexUniformBuffers[registerIndex] = uniformBuffer; 1020 } 1021 1022 if (uniformBlock->isReferencedByFragmentShader()) 1023 { 1024 unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS; 1025 ASSERT(fragmentUniformBuffers[registerIndex] == NULL); 1026 ASSERT(registerIndex < caps.maxFragmentUniformBlocks); 1027 fragmentUniformBuffers[registerIndex] = uniformBuffer; 1028 } 1029 } 1030 1031 return mProgram->getRenderer()->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers); 1032} 1033 1034bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader) 1035{ 1036 std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings(); 1037 std::vector<PackedVarying> &vertexVaryings = vertexShader->getVaryings(); 1038 1039 for (size_t fragVaryingIndex = 0; fragVaryingIndex < fragmentVaryings.size(); fragVaryingIndex++) 1040 { 1041 PackedVarying *input = &fragmentVaryings[fragVaryingIndex]; 1042 bool matched = false; 1043 1044 // Built-in varyings obey special rules 1045 if (input->isBuiltIn()) 1046 { 1047 continue; 1048 } 1049 1050 for (size_t vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++) 1051 { 1052 PackedVarying *output = &vertexVaryings[vertVaryingIndex]; 1053 if (output->name == input->name) 1054 { 1055 if (!linkValidateVaryings(infoLog, output->name, *input, *output)) 1056 { 1057 return false; 1058 } 1059 1060 output->registerIndex = input->registerIndex; 1061 output->columnIndex = input->columnIndex; 1062 1063 matched = true; 1064 break; 1065 } 1066 } 1067 1068 // We permit unmatched, unreferenced varyings 1069 if (!matched && input->staticUse) 1070 { 1071 infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str()); 1072 return false; 1073 } 1074 } 1075 1076 return true; 1077} 1078 1079bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length) 1080{ 1081#ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD 1082 return false; 1083#else 1084 ASSERT(binaryFormat == mProgram->getBinaryFormat()); 1085 1086 reset(); 1087 1088 BinaryInputStream stream(binary, length); 1089 1090 GLenum format = stream.readInt<GLenum>(); 1091 if (format != mProgram->getBinaryFormat()) 1092 { 1093 infoLog.append("Invalid program binary format."); 1094 return false; 1095 } 1096 1097 int majorVersion = stream.readInt<int>(); 1098 int minorVersion = stream.readInt<int>(); 1099 if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION) 1100 { 1101 infoLog.append("Invalid program binary version."); 1102 return false; 1103 } 1104 1105 unsigned char commitString[ANGLE_COMMIT_HASH_SIZE]; 1106 stream.readBytes(commitString, ANGLE_COMMIT_HASH_SIZE); 1107 if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0) 1108 { 1109 infoLog.append("Invalid program binary version."); 1110 return false; 1111 } 1112 1113 int compileFlags = stream.readInt<int>(); 1114 if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL) 1115 { 1116 infoLog.append("Mismatched compilation flags."); 1117 return false; 1118 } 1119 1120 for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i) 1121 { 1122 stream.readInt(&mLinkedAttribute[i].type); 1123 stream.readString(&mLinkedAttribute[i].name); 1124 stream.readInt(&mShaderAttributes[i].type); 1125 stream.readString(&mShaderAttributes[i].name); 1126 stream.readInt(&mSemanticIndex[i]); 1127 } 1128 1129 initAttributesByLayout(); 1130 1131 const unsigned int psSamplerCount = stream.readInt<unsigned int>(); 1132 for (unsigned int i = 0; i < psSamplerCount; ++i) 1133 { 1134 Sampler sampler; 1135 stream.readBool(&sampler.active); 1136 stream.readInt(&sampler.logicalTextureUnit); 1137 stream.readInt(&sampler.textureType); 1138 mSamplersPS.push_back(sampler); 1139 } 1140 const unsigned int vsSamplerCount = stream.readInt<unsigned int>(); 1141 for (unsigned int i = 0; i < vsSamplerCount; ++i) 1142 { 1143 Sampler sampler; 1144 stream.readBool(&sampler.active); 1145 stream.readInt(&sampler.logicalTextureUnit); 1146 stream.readInt(&sampler.textureType); 1147 mSamplersVS.push_back(sampler); 1148 } 1149 1150 stream.readInt(&mUsedVertexSamplerRange); 1151 stream.readInt(&mUsedPixelSamplerRange); 1152 stream.readBool(&mUsesPointSize); 1153 stream.readInt(&mShaderVersion); 1154 1155 const unsigned int uniformCount = stream.readInt<unsigned int>(); 1156 if (stream.error()) 1157 { 1158 infoLog.append("Invalid program binary."); 1159 return false; 1160 } 1161 1162 mUniforms.resize(uniformCount); 1163 for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++) 1164 { 1165 GLenum type = stream.readInt<GLenum>(); 1166 GLenum precision = stream.readInt<GLenum>(); 1167 std::string name = stream.readString(); 1168 unsigned int arraySize = stream.readInt<unsigned int>(); 1169 int blockIndex = stream.readInt<int>(); 1170 1171 int offset = stream.readInt<int>(); 1172 int arrayStride = stream.readInt<int>(); 1173 int matrixStride = stream.readInt<int>(); 1174 bool isRowMajorMatrix = stream.readBool(); 1175 1176 const sh::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix); 1177 1178 LinkedUniform *uniform = new LinkedUniform(type, precision, name, arraySize, blockIndex, blockInfo); 1179 1180 stream.readInt(&uniform->psRegisterIndex); 1181 stream.readInt(&uniform->vsRegisterIndex); 1182 stream.readInt(&uniform->registerCount); 1183 stream.readInt(&uniform->registerElement); 1184 1185 mUniforms[uniformIndex] = uniform; 1186 } 1187 1188 unsigned int uniformBlockCount = stream.readInt<unsigned int>(); 1189 if (stream.error()) 1190 { 1191 infoLog.append("Invalid program binary."); 1192 return false; 1193 } 1194 1195 mUniformBlocks.resize(uniformBlockCount); 1196 for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex) 1197 { 1198 std::string name = stream.readString(); 1199 unsigned int elementIndex = stream.readInt<unsigned int>(); 1200 unsigned int dataSize = stream.readInt<unsigned int>(); 1201 1202 UniformBlock *uniformBlock = new UniformBlock(name, elementIndex, dataSize); 1203 1204 stream.readInt(&uniformBlock->psRegisterIndex); 1205 stream.readInt(&uniformBlock->vsRegisterIndex); 1206 1207 unsigned int numMembers = stream.readInt<unsigned int>(); 1208 uniformBlock->memberUniformIndexes.resize(numMembers); 1209 for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++) 1210 { 1211 stream.readInt(&uniformBlock->memberUniformIndexes[blockMemberIndex]); 1212 } 1213 1214 mUniformBlocks[uniformBlockIndex] = uniformBlock; 1215 } 1216 1217 const unsigned int uniformIndexCount = stream.readInt<unsigned int>(); 1218 if (stream.error()) 1219 { 1220 infoLog.append("Invalid program binary."); 1221 return false; 1222 } 1223 1224 mUniformIndex.resize(uniformIndexCount); 1225 for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++) 1226 { 1227 stream.readString(&mUniformIndex[uniformIndexIndex].name); 1228 stream.readInt(&mUniformIndex[uniformIndexIndex].element); 1229 stream.readInt(&mUniformIndex[uniformIndexIndex].index); 1230 } 1231 1232 stream.readInt(&mTransformFeedbackBufferMode); 1233 const unsigned int transformFeedbackVaryingCount = stream.readInt<unsigned int>(); 1234 mTransformFeedbackLinkedVaryings.resize(transformFeedbackVaryingCount); 1235 for (unsigned int varyingIndex = 0; varyingIndex < transformFeedbackVaryingCount; varyingIndex++) 1236 { 1237 LinkedVarying &varying = mTransformFeedbackLinkedVaryings[varyingIndex]; 1238 1239 stream.readString(&varying.name); 1240 stream.readInt(&varying.type); 1241 stream.readInt(&varying.size); 1242 stream.readString(&varying.semanticName); 1243 stream.readInt(&varying.semanticIndex); 1244 stream.readInt(&varying.semanticIndexCount); 1245 } 1246 1247 const unsigned int vertexShaderCount = stream.readInt<unsigned int>(); 1248 for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++) 1249 { 1250 VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]; 1251 1252 for (size_t inputIndex = 0; inputIndex < MAX_VERTEX_ATTRIBS; inputIndex++) 1253 { 1254 VertexFormat *vertexInput = &inputLayout[inputIndex]; 1255 stream.readInt(&vertexInput->mType); 1256 stream.readInt(&vertexInput->mNormalized); 1257 stream.readInt(&vertexInput->mComponents); 1258 stream.readBool(&vertexInput->mPureInteger); 1259 } 1260 1261 unsigned int vertexShaderSize = stream.readInt<unsigned int>(); 1262 const unsigned char *vertexShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset(); 1263 rx::ShaderExecutable *shaderExecutable = mProgram->getRenderer()->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction), 1264 vertexShaderSize, rx::SHADER_VERTEX, 1265 mTransformFeedbackLinkedVaryings, 1266 (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); 1267 if (!shaderExecutable) 1268 { 1269 infoLog.append("Could not create vertex shader."); 1270 return false; 1271 } 1272 1273 // generated converted input layout 1274 GLenum signature[MAX_VERTEX_ATTRIBS]; 1275 mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature); 1276 1277 // add new binary 1278 mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable)); 1279 1280 stream.skip(vertexShaderSize); 1281 } 1282 1283 const size_t pixelShaderCount = stream.readInt<unsigned int>(); 1284 for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++) 1285 { 1286 const size_t outputCount = stream.readInt<unsigned int>(); 1287 std::vector<GLenum> outputs(outputCount); 1288 for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++) 1289 { 1290 stream.readInt(&outputs[outputIndex]); 1291 } 1292 1293 const size_t pixelShaderSize = stream.readInt<unsigned int>(); 1294 const unsigned char *pixelShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset(); 1295 rx::Renderer *renderer = mProgram->getRenderer(); 1296 rx::ShaderExecutable *shaderExecutable = renderer->loadExecutable(pixelShaderFunction, pixelShaderSize, 1297 rx::SHADER_PIXEL, mTransformFeedbackLinkedVaryings, 1298 (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); 1299 1300 if (!shaderExecutable) 1301 { 1302 infoLog.append("Could not create pixel shader."); 1303 return false; 1304 } 1305 1306 // add new binary 1307 mPixelExecutables.push_back(new PixelExecutable(outputs, shaderExecutable)); 1308 1309 stream.skip(pixelShaderSize); 1310 } 1311 1312 unsigned int geometryShaderSize = stream.readInt<unsigned int>(); 1313 1314 if (geometryShaderSize > 0) 1315 { 1316 const char *geometryShaderFunction = (const char*) binary + stream.offset(); 1317 rx::Renderer *renderer = mProgram->getRenderer(); 1318 mGeometryExecutable = renderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction), 1319 geometryShaderSize, rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings, 1320 (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS)); 1321 1322 if (!mGeometryExecutable) 1323 { 1324 infoLog.append("Could not create geometry shader."); 1325 return false; 1326 } 1327 stream.skip(geometryShaderSize); 1328 } 1329 1330 if (!mProgram->load(infoLog, &stream)) 1331 { 1332 return false; 1333 } 1334 1335 const char *ptr = (const char*) binary + stream.offset(); 1336 1337 const GUID *binaryIdentifier = (const GUID *) ptr; 1338 ptr += sizeof(GUID); 1339 1340 GUID identifier = mProgram->getRenderer()->getAdapterIdentifier(); 1341 if (memcmp(&identifier, binaryIdentifier, sizeof(GUID)) != 0) 1342 { 1343 infoLog.append("Invalid program binary."); 1344 return false; 1345 } 1346 1347 mProgram->initializeUniformStorage(mUniforms); 1348 1349 return true; 1350#endif // #ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD 1351} 1352 1353bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length) 1354{ 1355 if (binaryFormat) 1356 { 1357 *binaryFormat = mProgram->getBinaryFormat(); 1358 } 1359 1360 BinaryOutputStream stream; 1361 1362 stream.writeInt(mProgram->getBinaryFormat()); 1363 stream.writeInt(ANGLE_MAJOR_VERSION); 1364 stream.writeInt(ANGLE_MINOR_VERSION); 1365 stream.writeBytes(reinterpret_cast<const unsigned char*>(ANGLE_COMMIT_HASH), ANGLE_COMMIT_HASH_SIZE); 1366 stream.writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL); 1367 1368 for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i) 1369 { 1370 stream.writeInt(mLinkedAttribute[i].type); 1371 stream.writeString(mLinkedAttribute[i].name); 1372 stream.writeInt(mShaderAttributes[i].type); 1373 stream.writeString(mShaderAttributes[i].name); 1374 stream.writeInt(mSemanticIndex[i]); 1375 } 1376 1377 stream.writeInt(mSamplersPS.size()); 1378 for (unsigned int i = 0; i < mSamplersPS.size(); ++i) 1379 { 1380 stream.writeInt(mSamplersPS[i].active); 1381 stream.writeInt(mSamplersPS[i].logicalTextureUnit); 1382 stream.writeInt(mSamplersPS[i].textureType); 1383 } 1384 1385 stream.writeInt(mSamplersVS.size()); 1386 for (unsigned int i = 0; i < mSamplersVS.size(); ++i) 1387 { 1388 stream.writeInt(mSamplersVS[i].active); 1389 stream.writeInt(mSamplersVS[i].logicalTextureUnit); 1390 stream.writeInt(mSamplersVS[i].textureType); 1391 } 1392 1393 stream.writeInt(mUsedVertexSamplerRange); 1394 stream.writeInt(mUsedPixelSamplerRange); 1395 stream.writeInt(mUsesPointSize); 1396 stream.writeInt(mShaderVersion); 1397 1398 stream.writeInt(mUniforms.size()); 1399 for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex) 1400 { 1401 const LinkedUniform &uniform = *mUniforms[uniformIndex]; 1402 1403 stream.writeInt(uniform.type); 1404 stream.writeInt(uniform.precision); 1405 stream.writeString(uniform.name); 1406 stream.writeInt(uniform.arraySize); 1407 stream.writeInt(uniform.blockIndex); 1408 1409 stream.writeInt(uniform.blockInfo.offset); 1410 stream.writeInt(uniform.blockInfo.arrayStride); 1411 stream.writeInt(uniform.blockInfo.matrixStride); 1412 stream.writeInt(uniform.blockInfo.isRowMajorMatrix); 1413 1414 stream.writeInt(uniform.psRegisterIndex); 1415 stream.writeInt(uniform.vsRegisterIndex); 1416 stream.writeInt(uniform.registerCount); 1417 stream.writeInt(uniform.registerElement); 1418 } 1419 1420 stream.writeInt(mUniformBlocks.size()); 1421 for (size_t uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex) 1422 { 1423 const UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex]; 1424 1425 stream.writeString(uniformBlock.name); 1426 stream.writeInt(uniformBlock.elementIndex); 1427 stream.writeInt(uniformBlock.dataSize); 1428 1429 stream.writeInt(uniformBlock.memberUniformIndexes.size()); 1430 for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++) 1431 { 1432 stream.writeInt(uniformBlock.memberUniformIndexes[blockMemberIndex]); 1433 } 1434 1435 stream.writeInt(uniformBlock.psRegisterIndex); 1436 stream.writeInt(uniformBlock.vsRegisterIndex); 1437 } 1438 1439 stream.writeInt(mUniformIndex.size()); 1440 for (size_t i = 0; i < mUniformIndex.size(); ++i) 1441 { 1442 stream.writeString(mUniformIndex[i].name); 1443 stream.writeInt(mUniformIndex[i].element); 1444 stream.writeInt(mUniformIndex[i].index); 1445 } 1446 1447 stream.writeInt(mTransformFeedbackBufferMode); 1448 stream.writeInt(mTransformFeedbackLinkedVaryings.size()); 1449 for (size_t i = 0; i < mTransformFeedbackLinkedVaryings.size(); i++) 1450 { 1451 const LinkedVarying &varying = mTransformFeedbackLinkedVaryings[i]; 1452 1453 stream.writeString(varying.name); 1454 stream.writeInt(varying.type); 1455 stream.writeInt(varying.size); 1456 stream.writeString(varying.semanticName); 1457 stream.writeInt(varying.semanticIndex); 1458 stream.writeInt(varying.semanticIndexCount); 1459 } 1460 1461 stream.writeInt(mVertexExecutables.size()); 1462 for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++) 1463 { 1464 VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex]; 1465 1466 for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++) 1467 { 1468 const VertexFormat &vertexInput = vertexExecutable->inputs()[inputIndex]; 1469 stream.writeInt(vertexInput.mType); 1470 stream.writeInt(vertexInput.mNormalized); 1471 stream.writeInt(vertexInput.mComponents); 1472 stream.writeInt(vertexInput.mPureInteger); 1473 } 1474 1475 size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength(); 1476 stream.writeInt(vertexShaderSize); 1477 1478 const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction(); 1479 stream.writeBytes(vertexBlob, vertexShaderSize); 1480 } 1481 1482 stream.writeInt(mPixelExecutables.size()); 1483 for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++) 1484 { 1485 PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex]; 1486 1487 const std::vector<GLenum> outputs = pixelExecutable->outputSignature(); 1488 stream.writeInt(outputs.size()); 1489 for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++) 1490 { 1491 stream.writeInt(outputs[outputIndex]); 1492 } 1493 1494 size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength(); 1495 stream.writeInt(pixelShaderSize); 1496 1497 const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction(); 1498 stream.writeBytes(pixelBlob, pixelShaderSize); 1499 } 1500 1501 size_t geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0; 1502 stream.writeInt(geometryShaderSize); 1503 1504 if (mGeometryExecutable != NULL && geometryShaderSize > 0) 1505 { 1506 const uint8_t *geometryBlob = mGeometryExecutable->getFunction(); 1507 stream.writeBytes(geometryBlob, geometryShaderSize); 1508 } 1509 1510 if (!mProgram->save(&stream)) 1511 { 1512 if (length) 1513 { 1514 *length = 0; 1515 } 1516 1517 return false; 1518 } 1519 1520 GUID identifier = mProgram->getRenderer()->getAdapterIdentifier(); 1521 1522 GLsizei streamLength = stream.length(); 1523 const void *streamData = stream.data(); 1524 1525 GLsizei totalLength = streamLength + sizeof(GUID); 1526 if (totalLength > bufSize) 1527 { 1528 if (length) 1529 { 1530 *length = 0; 1531 } 1532 1533 return false; 1534 } 1535 1536 if (binary) 1537 { 1538 char *ptr = (char*) binary; 1539 1540 memcpy(ptr, streamData, streamLength); 1541 ptr += streamLength; 1542 1543 memcpy(ptr, &identifier, sizeof(GUID)); 1544 ptr += sizeof(GUID); 1545 1546 ASSERT(ptr - totalLength == binary); 1547 } 1548 1549 if (length) 1550 { 1551 *length = totalLength; 1552 } 1553 1554 return true; 1555} 1556 1557GLint ProgramBinary::getLength() 1558{ 1559 GLint length; 1560 if (save(NULL, NULL, INT_MAX, &length)) 1561 { 1562 return length; 1563 } 1564 else 1565 { 1566 return 0; 1567 } 1568} 1569 1570bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader, 1571 const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps) 1572{ 1573 if (!fragmentShader || !fragmentShader->isCompiled()) 1574 { 1575 return false; 1576 } 1577 ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER); 1578 1579 if (!vertexShader || !vertexShader->isCompiled()) 1580 { 1581 return false; 1582 } 1583 ASSERT(vertexShader->getType() == GL_VERTEX_SHADER); 1584 1585 reset(); 1586 1587 mSamplersPS.resize(caps.maxTextureImageUnits); 1588 mSamplersVS.resize(caps.maxVertexTextureImageUnits); 1589 1590 mTransformFeedbackBufferMode = transformFeedbackBufferMode; 1591 1592 rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation()); 1593 rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation()); 1594 1595 mShaderVersion = vertexShaderD3D->getShaderVersion(); 1596 1597 int registers; 1598 std::vector<LinkedVarying> linkedVaryings; 1599 if (!mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, ®isters, &linkedVaryings, &mOutputVariables)) 1600 { 1601 return false; 1602 } 1603 1604 mUsesPointSize = vertexShaderD3D->usesPointSize(); 1605 1606 bool success = true; 1607 1608 if (!linkAttributes(infoLog, attributeBindings, vertexShader)) 1609 { 1610 success = false; 1611 } 1612 1613 if (!linkUniforms(infoLog, *vertexShader, *fragmentShader, caps)) 1614 { 1615 success = false; 1616 } 1617 1618 // special case for gl_DepthRange, the only built-in uniform (also a struct) 1619 if (vertexShaderD3D->usesDepthRange() || fragmentShaderD3D->usesDepthRange()) 1620 { 1621 const sh::BlockMemberInfo &defaultInfo = sh::BlockMemberInfo::getDefaultBlockInfo(); 1622 1623 mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0, -1, defaultInfo)); 1624 mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0, -1, defaultInfo)); 1625 mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, defaultInfo)); 1626 } 1627 1628 if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, caps)) 1629 { 1630 success = false; 1631 } 1632 1633 if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings, 1634 transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings, caps)) 1635 { 1636 success = false; 1637 } 1638 1639 if (success) 1640 { 1641 VertexFormat defaultInputLayout[MAX_VERTEX_ATTRIBS]; 1642 GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout); 1643 rx::ShaderExecutable *defaultVertexExecutable = getVertexExecutableForInputLayout(defaultInputLayout); 1644 1645 std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(mProgram->getPixelShaderKey()); 1646 rx::ShaderExecutable *defaultPixelExecutable = getPixelExecutableForOutputLayout(defaultPixelOutput); 1647 1648 if (usesGeometryShader()) 1649 { 1650 std::string geometryHLSL = mProgram->getDynamicHLSL()->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D); 1651 mGeometryExecutable = mProgram->getRenderer()->compileToExecutable(infoLog, geometryHLSL.c_str(), 1652 rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings, 1653 (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), 1654 rx::ANGLE_D3D_WORKAROUND_NONE); 1655 } 1656 1657 if (!defaultVertexExecutable || !defaultPixelExecutable || (usesGeometryShader() && !mGeometryExecutable)) 1658 { 1659 infoLog.append("Failed to create D3D shaders."); 1660 success = false; 1661 reset(); 1662 } 1663 } 1664 1665 return success; 1666} 1667 1668// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices 1669bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader) 1670{ 1671 const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation()); 1672 1673 unsigned int usedLocations = 0; 1674 const std::vector<sh::Attribute> &shaderAttributes = vertexShader->getActiveAttributes(); 1675 1676 // Link attributes that have a binding location 1677 for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++) 1678 { 1679 const sh::Attribute &attribute = shaderAttributes[attributeIndex]; 1680 1681 ASSERT(attribute.staticUse); 1682 1683 const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location; 1684 1685 mShaderAttributes[attributeIndex] = attribute; 1686 1687 if (location != -1) // Set by glBindAttribLocation or by location layout qualifier 1688 { 1689 const int rows = VariableRegisterCount(attribute.type); 1690 1691 if (rows + location > MAX_VERTEX_ATTRIBS) 1692 { 1693 infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute.name.c_str(), location); 1694 1695 return false; 1696 } 1697 1698 for (int row = 0; row < rows; row++) 1699 { 1700 const int rowLocation = location + row; 1701 sh::ShaderVariable &linkedAttribute = mLinkedAttribute[rowLocation]; 1702 1703 // In GLSL 3.00, attribute aliasing produces a link error 1704 // In GLSL 1.00, attribute aliasing is allowed 1705 if (mShaderVersion >= 300) 1706 { 1707 if (!linkedAttribute.name.empty()) 1708 { 1709 infoLog.append("Attribute '%s' aliases attribute '%s' at location %d", attribute.name.c_str(), linkedAttribute.name.c_str(), rowLocation); 1710 return false; 1711 } 1712 } 1713 1714 linkedAttribute = attribute; 1715 usedLocations |= 1 << rowLocation; 1716 } 1717 } 1718 } 1719 1720 // Link attributes that don't have a binding location 1721 for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++) 1722 { 1723 const sh::Attribute &attribute = shaderAttributes[attributeIndex]; 1724 1725 ASSERT(attribute.staticUse); 1726 1727 const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location; 1728 1729 if (location == -1) // Not set by glBindAttribLocation or by location layout qualifier 1730 { 1731 int rows = VariableRegisterCount(attribute.type); 1732 int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS); 1733 1734 if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS) 1735 { 1736 infoLog.append("Too many active attributes (%s)", attribute.name.c_str()); 1737 1738 return false; // Fail to link 1739 } 1740 1741 mLinkedAttribute[availableIndex] = attribute; 1742 } 1743 } 1744 1745 for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; ) 1746 { 1747 int index = vertexShaderD3D->getSemanticIndex(mLinkedAttribute[attributeIndex].name); 1748 int rows = VariableRegisterCount(mLinkedAttribute[attributeIndex].type); 1749 1750 for (int r = 0; r < rows; r++) 1751 { 1752 mSemanticIndex[attributeIndex++] = index++; 1753 } 1754 } 1755 1756 initAttributesByLayout(); 1757 1758 return true; 1759} 1760 1761bool ProgramBinary::linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, const sh::ShaderVariable &vertexVariable, 1762 const sh::ShaderVariable &fragmentVariable, bool validatePrecision) 1763{ 1764 if (vertexVariable.type != fragmentVariable.type) 1765 { 1766 infoLog.append("Types for %s differ between vertex and fragment shaders", variableName.c_str()); 1767 return false; 1768 } 1769 if (vertexVariable.arraySize != fragmentVariable.arraySize) 1770 { 1771 infoLog.append("Array sizes for %s differ between vertex and fragment shaders", variableName.c_str()); 1772 return false; 1773 } 1774 if (validatePrecision && vertexVariable.precision != fragmentVariable.precision) 1775 { 1776 infoLog.append("Precisions for %s differ between vertex and fragment shaders", variableName.c_str()); 1777 return false; 1778 } 1779 1780 if (vertexVariable.fields.size() != fragmentVariable.fields.size()) 1781 { 1782 infoLog.append("Structure lengths for %s differ between vertex and fragment shaders", variableName.c_str()); 1783 return false; 1784 } 1785 const unsigned int numMembers = vertexVariable.fields.size(); 1786 for (unsigned int memberIndex = 0; memberIndex < numMembers; memberIndex++) 1787 { 1788 const sh::ShaderVariable &vertexMember = vertexVariable.fields[memberIndex]; 1789 const sh::ShaderVariable &fragmentMember = fragmentVariable.fields[memberIndex]; 1790 1791 if (vertexMember.name != fragmentMember.name) 1792 { 1793 infoLog.append("Name mismatch for field '%d' of %s: (in vertex: '%s', in fragment: '%s')", 1794 memberIndex, variableName.c_str(), 1795 vertexMember.name.c_str(), fragmentMember.name.c_str()); 1796 return false; 1797 } 1798 1799 const std::string memberName = variableName.substr(0, variableName.length() - 1) + "." + 1800 vertexMember.name + "'"; 1801 1802 if (!linkValidateVariablesBase(infoLog, vertexMember.name, vertexMember, fragmentMember, validatePrecision)) 1803 { 1804 return false; 1805 } 1806 } 1807 1808 return true; 1809} 1810 1811bool ProgramBinary::linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform) 1812{ 1813 if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true)) 1814 { 1815 return false; 1816 } 1817 1818 return true; 1819} 1820 1821bool ProgramBinary::linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying) 1822{ 1823 if (!linkValidateVariablesBase(infoLog, varyingName, vertexVarying, fragmentVarying, false)) 1824 { 1825 return false; 1826 } 1827 1828 if (vertexVarying.interpolation != fragmentVarying.interpolation) 1829 { 1830 infoLog.append("Interpolation types for %s differ between vertex and fragment shaders", varyingName.c_str()); 1831 return false; 1832 } 1833 1834 return true; 1835} 1836 1837bool ProgramBinary::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform) 1838{ 1839 if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true)) 1840 { 1841 return false; 1842 } 1843 1844 if (vertexUniform.isRowMajorLayout != fragmentUniform.isRowMajorLayout) 1845 { 1846 infoLog.append("Matrix packings for %s differ between vertex and fragment shaders", uniformName.c_str()); 1847 return false; 1848 } 1849 1850 return true; 1851} 1852 1853bool ProgramBinary::linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps) 1854{ 1855 const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader.getImplementation()); 1856 const rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader.getImplementation()); 1857 1858 const std::vector<sh::Uniform> &vertexUniforms = vertexShader.getUniforms(); 1859 const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader.getUniforms(); 1860 1861 // Check that uniforms defined in the vertex and fragment shaders are identical 1862 typedef std::map<std::string, const sh::Uniform*> UniformMap; 1863 UniformMap linkedUniforms; 1864 1865 for (unsigned int vertexUniformIndex = 0; vertexUniformIndex < vertexUniforms.size(); vertexUniformIndex++) 1866 { 1867 const sh::Uniform &vertexUniform = vertexUniforms[vertexUniformIndex]; 1868 linkedUniforms[vertexUniform.name] = &vertexUniform; 1869 } 1870 1871 for (unsigned int fragmentUniformIndex = 0; fragmentUniformIndex < fragmentUniforms.size(); fragmentUniformIndex++) 1872 { 1873 const sh::Uniform &fragmentUniform = fragmentUniforms[fragmentUniformIndex]; 1874 UniformMap::const_iterator entry = linkedUniforms.find(fragmentUniform.name); 1875 if (entry != linkedUniforms.end()) 1876 { 1877 const sh::Uniform &vertexUniform = *entry->second; 1878 const std::string &uniformName = "uniform '" + vertexUniform.name + "'"; 1879 if (!linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform)) 1880 { 1881 return false; 1882 } 1883 } 1884 } 1885 1886 for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++) 1887 { 1888 const sh::Uniform &uniform = vertexUniforms[uniformIndex]; 1889 1890 if (uniform.staticUse) 1891 { 1892 defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name)); 1893 } 1894 } 1895 1896 for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++) 1897 { 1898 const sh::Uniform &uniform = fragmentUniforms[uniformIndex]; 1899 1900 if (uniform.staticUse) 1901 { 1902 defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name)); 1903 } 1904 } 1905 1906 if (!indexUniforms(infoLog, caps)) 1907 { 1908 return false; 1909 } 1910 1911 mProgram->initializeUniformStorage(mUniforms); 1912 1913 return true; 1914} 1915 1916void ProgramBinary::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister) 1917{ 1918 ShShaderOutput outputType = rx::ShaderD3D::getCompilerOutputType(shader); 1919 sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType)); 1920 encoder.skipRegisters(uniformRegister); 1921 1922 defineUniform(shader, uniform, uniform.name, &encoder); 1923} 1924 1925void ProgramBinary::defineUniform(GLenum shader, const sh::ShaderVariable &uniform, 1926 const std::string &fullName, sh::HLSLBlockEncoder *encoder) 1927{ 1928 if (uniform.isStruct()) 1929 { 1930 for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++) 1931 { 1932 const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : ""); 1933 1934 encoder->enterAggregateType(); 1935 1936 for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++) 1937 { 1938 const sh::ShaderVariable &field = uniform.fields[fieldIndex]; 1939 const std::string &fieldFullName = (fullName + elementString + "." + field.name); 1940 1941 defineUniform(shader, field, fieldFullName, encoder); 1942 } 1943 1944 encoder->exitAggregateType(); 1945 } 1946 } 1947 else // Not a struct 1948 { 1949 // Arrays are treated as aggregate types 1950 if (uniform.isArray()) 1951 { 1952 encoder->enterAggregateType(); 1953 } 1954 1955 LinkedUniform *linkedUniform = getUniformByName(fullName); 1956 1957 if (!linkedUniform) 1958 { 1959 linkedUniform = new LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize, 1960 -1, sh::BlockMemberInfo::getDefaultBlockInfo()); 1961 ASSERT(linkedUniform); 1962 linkedUniform->registerElement = encoder->getCurrentElement(); 1963 mUniforms.push_back(linkedUniform); 1964 } 1965 1966 ASSERT(linkedUniform->registerElement == encoder->getCurrentElement()); 1967 1968 if (shader == GL_FRAGMENT_SHADER) 1969 { 1970 linkedUniform->psRegisterIndex = encoder->getCurrentRegister(); 1971 } 1972 else if (shader == GL_VERTEX_SHADER) 1973 { 1974 linkedUniform->vsRegisterIndex = encoder->getCurrentRegister(); 1975 } 1976 else UNREACHABLE(); 1977 1978 // Advance the uniform offset, to track registers allocation for structs 1979 encoder->encodeType(uniform.type, uniform.arraySize, false); 1980 1981 // Arrays are treated as aggregate types 1982 if (uniform.isArray()) 1983 { 1984 encoder->exitAggregateType(); 1985 } 1986 } 1987} 1988 1989bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps) 1990{ 1991 ASSERT(IsSampler(uniform.type)); 1992 ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX); 1993 1994 if (uniform.vsRegisterIndex != GL_INVALID_INDEX) 1995 { 1996 if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS, 1997 &mUsedVertexSamplerRange)) 1998 { 1999 infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).", 2000 mSamplersVS.size()); 2001 return false; 2002 } 2003 2004 unsigned int maxVertexVectors = mProgram->getRenderer()->getReservedVertexUniformVectors() + caps.maxVertexUniformVectors; 2005 if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors) 2006 { 2007 infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)", 2008 caps.maxVertexUniformVectors); 2009 return false; 2010 } 2011 } 2012 2013 if (uniform.psRegisterIndex != GL_INVALID_INDEX) 2014 { 2015 if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS, 2016 &mUsedPixelSamplerRange)) 2017 { 2018 infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", 2019 mSamplersPS.size()); 2020 return false; 2021 } 2022 2023 unsigned int maxFragmentVectors = mProgram->getRenderer()->getReservedFragmentUniformVectors() + caps.maxFragmentUniformVectors; 2024 if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors) 2025 { 2026 infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)", 2027 caps.maxFragmentUniformVectors); 2028 return false; 2029 } 2030 } 2031 2032 return true; 2033} 2034 2035bool ProgramBinary::indexUniforms(InfoLog &infoLog, const Caps &caps) 2036{ 2037 for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) 2038 { 2039 const LinkedUniform &uniform = *mUniforms[uniformIndex]; 2040 2041 if (IsSampler(uniform.type)) 2042 { 2043 if (!indexSamplerUniform(uniform, infoLog, caps)) 2044 { 2045 return false; 2046 } 2047 } 2048 2049 for (unsigned int arrayElementIndex = 0; arrayElementIndex < uniform.elementCount(); arrayElementIndex++) 2050 { 2051 mUniformIndex.push_back(VariableLocation(uniform.name, arrayElementIndex, uniformIndex)); 2052 } 2053 } 2054 2055 return true; 2056} 2057 2058bool ProgramBinary::assignSamplers(unsigned int startSamplerIndex, 2059 GLenum samplerType, 2060 unsigned int samplerCount, 2061 std::vector<Sampler> &outSamplers, 2062 GLuint *outUsedRange) 2063{ 2064 unsigned int samplerIndex = startSamplerIndex; 2065 2066 do 2067 { 2068 if (samplerIndex < outSamplers.size()) 2069 { 2070 Sampler& sampler = outSamplers[samplerIndex]; 2071 sampler.active = true; 2072 sampler.textureType = GetTextureType(samplerType); 2073 sampler.logicalTextureUnit = 0; 2074 *outUsedRange = std::max(samplerIndex + 1, *outUsedRange); 2075 } 2076 else 2077 { 2078 return false; 2079 } 2080 2081 samplerIndex++; 2082 } while (samplerIndex < startSamplerIndex + samplerCount); 2083 2084 return true; 2085} 2086 2087bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock) 2088{ 2089 const char* blockName = vertexInterfaceBlock.name.c_str(); 2090 2091 // validate blocks for the same member types 2092 if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size()) 2093 { 2094 infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName); 2095 return false; 2096 } 2097 2098 if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize) 2099 { 2100 infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName); 2101 return false; 2102 } 2103 2104 if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout) 2105 { 2106 infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName); 2107 return false; 2108 } 2109 2110 const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size(); 2111 for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++) 2112 { 2113 const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex]; 2114 const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex]; 2115 2116 if (vertexMember.name != fragmentMember.name) 2117 { 2118 infoLog.append("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')", 2119 blockMemberIndex, blockName, vertexMember.name.c_str(), fragmentMember.name.c_str()); 2120 return false; 2121 } 2122 2123 std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'"; 2124 if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember)) 2125 { 2126 return false; 2127 } 2128 } 2129 2130 return true; 2131} 2132 2133bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps) 2134{ 2135 const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks(); 2136 const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks(); 2137 2138 // Check that interface blocks defined in the vertex and fragment shaders are identical 2139 typedef std::map<std::string, const sh::InterfaceBlock*> UniformBlockMap; 2140 UniformBlockMap linkedUniformBlocks; 2141 2142 for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++) 2143 { 2144 const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex]; 2145 linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock; 2146 } 2147 2148 for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++) 2149 { 2150 const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex]; 2151 UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name); 2152 if (entry != linkedUniformBlocks.end()) 2153 { 2154 const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second; 2155 if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock)) 2156 { 2157 return false; 2158 } 2159 } 2160 } 2161 2162 for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++) 2163 { 2164 const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex]; 2165 2166 // Note: shared and std140 layouts are always considered active 2167 if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) 2168 { 2169 if (!defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps)) 2170 { 2171 return false; 2172 } 2173 } 2174 } 2175 2176 for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++) 2177 { 2178 const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex]; 2179 2180 // Note: shared and std140 layouts are always considered active 2181 if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) 2182 { 2183 if (!defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps)) 2184 { 2185 return false; 2186 } 2187 } 2188 } 2189 2190 return true; 2191} 2192 2193bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings, 2194 const std::vector<std::string> &transformFeedbackVaryingNames, 2195 GLenum transformFeedbackBufferMode, 2196 std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings, 2197 const Caps &caps) const 2198{ 2199 size_t totalComponents = 0; 2200 2201 // Gather the linked varyings that are used for transform feedback, they should all exist. 2202 outTransformFeedbackLinkedVaryings->clear(); 2203 for (size_t i = 0; i < transformFeedbackVaryingNames.size(); i++) 2204 { 2205 bool found = false; 2206 for (size_t j = 0; j < linkedVaryings.size(); j++) 2207 { 2208 if (transformFeedbackVaryingNames[i] == linkedVaryings[j].name) 2209 { 2210 for (size_t k = 0; k < outTransformFeedbackLinkedVaryings->size(); k++) 2211 { 2212 if (outTransformFeedbackLinkedVaryings->at(k).name == linkedVaryings[j].name) 2213 { 2214 infoLog.append("Two transform feedback varyings specify the same output variable (%s).", linkedVaryings[j].name.c_str()); 2215 return false; 2216 } 2217 } 2218 2219 size_t componentCount = linkedVaryings[j].semanticIndexCount * 4; 2220 if (transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS && 2221 componentCount > caps.maxTransformFeedbackSeparateComponents) 2222 { 2223 infoLog.append("Transform feedback varying's %s components (%u) exceed the maximum separate components (%u).", 2224 linkedVaryings[j].name.c_str(), componentCount, caps.maxTransformFeedbackSeparateComponents); 2225 return false; 2226 } 2227 2228 totalComponents += componentCount; 2229 2230 outTransformFeedbackLinkedVaryings->push_back(linkedVaryings[j]); 2231 found = true; 2232 break; 2233 } 2234 } 2235 2236 // All transform feedback varyings are expected to exist since packVaryings checks for them. 2237 ASSERT(found); 2238 } 2239 2240 if (transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && totalComponents > caps.maxTransformFeedbackInterleavedComponents) 2241 { 2242 infoLog.append("Transform feedback varying total components (%u) exceed the maximum interleaved components (%u).", 2243 totalComponents, caps.maxTransformFeedbackInterleavedComponents); 2244 return false; 2245 } 2246 2247 return true; 2248} 2249 2250template <typename VarT> 2251void ProgramBinary::defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex, 2252 sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes, 2253 bool inRowMajorLayout) 2254{ 2255 for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++) 2256 { 2257 const VarT &field = fields[uniformIndex]; 2258 const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name); 2259 2260 if (field.isStruct()) 2261 { 2262 bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field)); 2263 2264 for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++) 2265 { 2266 encoder->enterAggregateType(); 2267 2268 const std::string uniformElementName = fieldName + (field.isArray() ? ArrayString(arrayElement) : ""); 2269 defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes, rowMajorLayout); 2270 2271 encoder->exitAggregateType(); 2272 } 2273 } 2274 else 2275 { 2276 bool isRowMajorMatrix = (IsMatrixType(field.type) && inRowMajorLayout); 2277 2278 sh::BlockMemberInfo memberInfo = encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix); 2279 2280 LinkedUniform *newUniform = new LinkedUniform(field.type, field.precision, fieldName, field.arraySize, 2281 blockIndex, memberInfo); 2282 2283 // add to uniform list, but not index, since uniform block uniforms have no location 2284 blockUniformIndexes->push_back(mUniforms.size()); 2285 mUniforms.push_back(newUniform); 2286 } 2287 } 2288} 2289 2290bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps) 2291{ 2292 const rx::ShaderD3D* shaderD3D = rx::ShaderD3D::makeShaderD3D(shader.getImplementation()); 2293 2294 // create uniform block entries if they do not exist 2295 if (getUniformBlockIndex(interfaceBlock.name) == GL_INVALID_INDEX) 2296 { 2297 std::vector<unsigned int> blockUniformIndexes; 2298 const unsigned int blockIndex = mUniformBlocks.size(); 2299 2300 // define member uniforms 2301 sh::BlockLayoutEncoder *encoder = NULL; 2302 2303 if (interfaceBlock.layout == sh::BLOCKLAYOUT_STANDARD) 2304 { 2305 encoder = new sh::Std140BlockEncoder; 2306 } 2307 else 2308 { 2309 encoder = new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED); 2310 } 2311 ASSERT(encoder); 2312 2313 defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes, interfaceBlock.isRowMajorLayout); 2314 2315 size_t dataSize = encoder->getBlockSize(); 2316 2317 // create all the uniform blocks 2318 if (interfaceBlock.arraySize > 0) 2319 { 2320 for (unsigned int uniformBlockElement = 0; uniformBlockElement < interfaceBlock.arraySize; uniformBlockElement++) 2321 { 2322 UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, uniformBlockElement, dataSize); 2323 newUniformBlock->memberUniformIndexes = blockUniformIndexes; 2324 mUniformBlocks.push_back(newUniformBlock); 2325 } 2326 } 2327 else 2328 { 2329 UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, GL_INVALID_INDEX, dataSize); 2330 newUniformBlock->memberUniformIndexes = blockUniformIndexes; 2331 mUniformBlocks.push_back(newUniformBlock); 2332 } 2333 } 2334 2335 if (interfaceBlock.staticUse) 2336 { 2337 // Assign registers to the uniform blocks 2338 const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name); 2339 const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize); 2340 ASSERT(blockIndex != GL_INVALID_INDEX); 2341 ASSERT(blockIndex + elementCount <= mUniformBlocks.size()); 2342 2343 unsigned int interfaceBlockRegister = shaderD3D->getInterfaceBlockRegister(interfaceBlock.name); 2344 2345 for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++) 2346 { 2347 UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement]; 2348 ASSERT(uniformBlock->name == interfaceBlock.name); 2349 2350 if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(), 2351 interfaceBlockRegister + uniformBlockElement, caps)) 2352 { 2353 return false; 2354 } 2355 } 2356 } 2357 2358 return true; 2359} 2360 2361bool ProgramBinary::assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps) 2362{ 2363 if (shader == GL_VERTEX_SHADER) 2364 { 2365 uniformBlock->vsRegisterIndex = registerIndex; 2366 if (registerIndex - mProgram->getRenderer()->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks) 2367 { 2368 infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", caps.maxVertexUniformBlocks); 2369 return false; 2370 } 2371 } 2372 else if (shader == GL_FRAGMENT_SHADER) 2373 { 2374 uniformBlock->psRegisterIndex = registerIndex; 2375 if (registerIndex - mProgram->getRenderer()->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks) 2376 { 2377 infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", caps.maxFragmentUniformBlocks); 2378 return false; 2379 } 2380 } 2381 else UNREACHABLE(); 2382 2383 return true; 2384} 2385 2386bool ProgramBinary::isValidated() const 2387{ 2388 return mValidated; 2389} 2390 2391void ProgramBinary::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const 2392{ 2393 // Skip over inactive attributes 2394 unsigned int activeAttribute = 0; 2395 unsigned int attribute; 2396 for (attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) 2397 { 2398 if (mLinkedAttribute[attribute].name.empty()) 2399 { 2400 continue; 2401 } 2402 2403 if (activeAttribute == index) 2404 { 2405 break; 2406 } 2407 2408 activeAttribute++; 2409 } 2410 2411 if (bufsize > 0) 2412 { 2413 const char *string = mLinkedAttribute[attribute].name.c_str(); 2414 2415 strncpy(name, string, bufsize); 2416 name[bufsize - 1] = '\0'; 2417 2418 if (length) 2419 { 2420 *length = strlen(name); 2421 } 2422 } 2423 2424 *size = 1; // Always a single 'type' instance 2425 2426 *type = mLinkedAttribute[attribute].type; 2427} 2428 2429GLint ProgramBinary::getActiveAttributeCount() const 2430{ 2431 int count = 0; 2432 2433 for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) 2434 { 2435 if (!mLinkedAttribute[attributeIndex].name.empty()) 2436 { 2437 count++; 2438 } 2439 } 2440 2441 return count; 2442} 2443 2444GLint ProgramBinary::getActiveAttributeMaxLength() const 2445{ 2446 int maxLength = 0; 2447 2448 for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) 2449 { 2450 if (!mLinkedAttribute[attributeIndex].name.empty()) 2451 { 2452 maxLength = std::max((int)(mLinkedAttribute[attributeIndex].name.length() + 1), maxLength); 2453 } 2454 } 2455 2456 return maxLength; 2457} 2458 2459void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const 2460{ 2461 ASSERT(index < mUniforms.size()); // index must be smaller than getActiveUniformCount() 2462 2463 if (bufsize > 0) 2464 { 2465 std::string string = mUniforms[index]->name; 2466 2467 if (mUniforms[index]->isArray()) 2468 { 2469 string += "[0]"; 2470 } 2471 2472 strncpy(name, string.c_str(), bufsize); 2473 name[bufsize - 1] = '\0'; 2474 2475 if (length) 2476 { 2477 *length = strlen(name); 2478 } 2479 } 2480 2481 *size = mUniforms[index]->elementCount(); 2482 2483 *type = mUniforms[index]->type; 2484} 2485 2486GLint ProgramBinary::getActiveUniformCount() const 2487{ 2488 return mUniforms.size(); 2489} 2490 2491GLint ProgramBinary::getActiveUniformMaxLength() const 2492{ 2493 int maxLength = 0; 2494 2495 unsigned int numUniforms = mUniforms.size(); 2496 for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++) 2497 { 2498 if (!mUniforms[uniformIndex]->name.empty()) 2499 { 2500 int length = (int)(mUniforms[uniformIndex]->name.length() + 1); 2501 if (mUniforms[uniformIndex]->isArray()) 2502 { 2503 length += 3; // Counting in "[0]". 2504 } 2505 maxLength = std::max(length, maxLength); 2506 } 2507 } 2508 2509 return maxLength; 2510} 2511 2512GLint ProgramBinary::getActiveUniformi(GLuint index, GLenum pname) const 2513{ 2514 const gl::LinkedUniform& uniform = *mUniforms[index]; 2515 2516 switch (pname) 2517 { 2518 case GL_UNIFORM_TYPE: return static_cast<GLint>(uniform.type); 2519 case GL_UNIFORM_SIZE: return static_cast<GLint>(uniform.elementCount()); 2520 case GL_UNIFORM_NAME_LENGTH: return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0)); 2521 case GL_UNIFORM_BLOCK_INDEX: return uniform.blockIndex; 2522 2523 case GL_UNIFORM_OFFSET: return uniform.blockInfo.offset; 2524 case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride; 2525 case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride; 2526 case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix); 2527 2528 default: 2529 UNREACHABLE(); 2530 break; 2531 } 2532 return 0; 2533} 2534 2535bool ProgramBinary::isValidUniformLocation(GLint location) const 2536{ 2537 ASSERT(rx::IsIntegerCastSafe<GLint>(mUniformIndex.size())); 2538 return (location >= 0 && location < static_cast<GLint>(mUniformIndex.size())); 2539} 2540 2541LinkedUniform *ProgramBinary::getUniformByLocation(GLint location) const 2542{ 2543 ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformIndex.size()); 2544 return mUniforms[mUniformIndex[location].index]; 2545} 2546 2547LinkedUniform *ProgramBinary::getUniformByName(const std::string &name) const 2548{ 2549 for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) 2550 { 2551 if (mUniforms[uniformIndex]->name == name) 2552 { 2553 return mUniforms[uniformIndex]; 2554 } 2555 } 2556 2557 return NULL; 2558} 2559 2560void ProgramBinary::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const 2561{ 2562 ASSERT(uniformBlockIndex < mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount() 2563 2564 const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex]; 2565 2566 if (bufSize > 0) 2567 { 2568 std::string string = uniformBlock.name; 2569 2570 if (uniformBlock.isArrayElement()) 2571 { 2572 string += ArrayString(uniformBlock.elementIndex); 2573 } 2574 2575 strncpy(uniformBlockName, string.c_str(), bufSize); 2576 uniformBlockName[bufSize - 1] = '\0'; 2577 2578 if (length) 2579 { 2580 *length = strlen(uniformBlockName); 2581 } 2582 } 2583} 2584 2585void ProgramBinary::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const 2586{ 2587 ASSERT(uniformBlockIndex < mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount() 2588 2589 const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex]; 2590 2591 switch (pname) 2592 { 2593 case GL_UNIFORM_BLOCK_DATA_SIZE: 2594 *params = static_cast<GLint>(uniformBlock.dataSize); 2595 break; 2596 case GL_UNIFORM_BLOCK_NAME_LENGTH: 2597 *params = static_cast<GLint>(uniformBlock.name.size() + 1 + (uniformBlock.isArrayElement() ? 3 : 0)); 2598 break; 2599 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: 2600 *params = static_cast<GLint>(uniformBlock.memberUniformIndexes.size()); 2601 break; 2602 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: 2603 { 2604 for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++) 2605 { 2606 params[blockMemberIndex] = static_cast<GLint>(uniformBlock.memberUniformIndexes[blockMemberIndex]); 2607 } 2608 } 2609 break; 2610 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: 2611 *params = static_cast<GLint>(uniformBlock.isReferencedByVertexShader()); 2612 break; 2613 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: 2614 *params = static_cast<GLint>(uniformBlock.isReferencedByFragmentShader()); 2615 break; 2616 default: UNREACHABLE(); 2617 } 2618} 2619 2620GLuint ProgramBinary::getActiveUniformBlockCount() const 2621{ 2622 return mUniformBlocks.size(); 2623} 2624 2625GLuint ProgramBinary::getActiveUniformBlockMaxLength() const 2626{ 2627 unsigned int maxLength = 0; 2628 2629 unsigned int numUniformBlocks = mUniformBlocks.size(); 2630 for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++) 2631 { 2632 const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex]; 2633 if (!uniformBlock.name.empty()) 2634 { 2635 const unsigned int length = uniformBlock.name.length() + 1; 2636 2637 // Counting in "[0]". 2638 const unsigned int arrayLength = (uniformBlock.isArrayElement() ? 3 : 0); 2639 2640 maxLength = std::max(length + arrayLength, maxLength); 2641 } 2642 } 2643 2644 return maxLength; 2645} 2646 2647void ProgramBinary::validate(InfoLog &infoLog, const Caps &caps) 2648{ 2649 applyUniforms(); 2650 if (!validateSamplers(&infoLog, caps)) 2651 { 2652 mValidated = false; 2653 } 2654 else 2655 { 2656 mValidated = true; 2657 } 2658} 2659 2660bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps) 2661{ 2662 // if any two active samplers in a program are of different types, but refer to the same 2663 // texture image unit, and this is the current program, then ValidateProgram will fail, and 2664 // DrawArrays and DrawElements will issue the INVALID_OPERATION error. 2665 updateSamplerMapping(); 2666 2667 std::vector<GLenum> textureUnitTypes(caps.maxCombinedTextureImageUnits, GL_NONE); 2668 2669 for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i) 2670 { 2671 if (mSamplersPS[i].active) 2672 { 2673 unsigned int unit = mSamplersPS[i].logicalTextureUnit; 2674 2675 if (unit >= textureUnitTypes.size()) 2676 { 2677 if (infoLog) 2678 { 2679 infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size()); 2680 } 2681 2682 return false; 2683 } 2684 2685 if (textureUnitTypes[unit] != GL_NONE) 2686 { 2687 if (mSamplersPS[i].textureType != textureUnitTypes[unit]) 2688 { 2689 if (infoLog) 2690 { 2691 infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit); 2692 } 2693 2694 return false; 2695 } 2696 } 2697 else 2698 { 2699 textureUnitTypes[unit] = mSamplersPS[i].textureType; 2700 } 2701 } 2702 } 2703 2704 for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i) 2705 { 2706 if (mSamplersVS[i].active) 2707 { 2708 unsigned int unit = mSamplersVS[i].logicalTextureUnit; 2709 2710 if (unit >= textureUnitTypes.size()) 2711 { 2712 if (infoLog) 2713 { 2714 infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size()); 2715 } 2716 2717 return false; 2718 } 2719 2720 if (textureUnitTypes[unit] != GL_NONE) 2721 { 2722 if (mSamplersVS[i].textureType != textureUnitTypes[unit]) 2723 { 2724 if (infoLog) 2725 { 2726 infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit); 2727 } 2728 2729 return false; 2730 } 2731 } 2732 else 2733 { 2734 textureUnitTypes[unit] = mSamplersVS[i].textureType; 2735 } 2736 } 2737 } 2738 2739 return true; 2740} 2741 2742ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(GL_TEXTURE_2D) 2743{ 2744} 2745 2746struct AttributeSorter 2747{ 2748 AttributeSorter(const int (&semanticIndices)[MAX_VERTEX_ATTRIBS]) 2749 : originalIndices(semanticIndices) 2750 { 2751 } 2752 2753 bool operator()(int a, int b) 2754 { 2755 if (originalIndices[a] == -1) return false; 2756 if (originalIndices[b] == -1) return true; 2757 return (originalIndices[a] < originalIndices[b]); 2758 } 2759 2760 const int (&originalIndices)[MAX_VERTEX_ATTRIBS]; 2761}; 2762 2763void ProgramBinary::initAttributesByLayout() 2764{ 2765 for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 2766 { 2767 mAttributesByLayout[i] = i; 2768 } 2769 2770 std::sort(&mAttributesByLayout[0], &mAttributesByLayout[MAX_VERTEX_ATTRIBS], AttributeSorter(mSemanticIndex)); 2771} 2772 2773void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const 2774{ 2775 rx::TranslatedAttribute oldTranslatedAttributes[MAX_VERTEX_ATTRIBS]; 2776 2777 for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 2778 { 2779 oldTranslatedAttributes[i] = attributes[i]; 2780 } 2781 2782 for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 2783 { 2784 int oldIndex = mAttributesByLayout[i]; 2785 sortedSemanticIndices[i] = mSemanticIndex[oldIndex]; 2786 attributes[i] = oldTranslatedAttributes[oldIndex]; 2787 } 2788} 2789 2790void ProgramBinary::reset() 2791{ 2792 SafeDeleteContainer(mVertexExecutables); 2793 SafeDeleteContainer(mPixelExecutables); 2794 2795 SafeDelete(mGeometryExecutable); 2796 2797 mTransformFeedbackBufferMode = GL_NONE; 2798 mTransformFeedbackLinkedVaryings.clear(); 2799 2800 mSamplersPS.clear(); 2801 mSamplersVS.clear(); 2802 2803 mUsedVertexSamplerRange = 0; 2804 mUsedPixelSamplerRange = 0; 2805 mUsesPointSize = false; 2806 mShaderVersion = 0; 2807 mDirtySamplerMapping = true; 2808 2809 SafeDeleteContainer(mUniforms); 2810 SafeDeleteContainer(mUniformBlocks); 2811 mUniformIndex.clear(); 2812 mOutputVariables.clear(); 2813 2814 mProgram->reset(); 2815 2816 mValidated = false; 2817} 2818 2819} 2820