1 // 2 // Copyright 2002 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.h: Defines 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 #ifndef LIBANGLE_PROGRAM_H_ 11 #define LIBANGLE_PROGRAM_H_ 12 13 #include <GLES2/gl2.h> 14 #include <GLSLANG/ShaderVars.h> 15 16 #include <array> 17 #include <map> 18 #include <set> 19 #include <sstream> 20 #include <string> 21 #include <vector> 22 23 #include "common/Optional.h" 24 #include "common/angleutils.h" 25 #include "common/mathutil.h" 26 #include "common/utilities.h" 27 28 #include "libANGLE/Constants.h" 29 #include "libANGLE/Debug.h" 30 #include "libANGLE/Error.h" 31 #include "libANGLE/RefCountObject.h" 32 #include "libANGLE/Uniform.h" 33 #include "libANGLE/angletypes.h" 34 35 namespace rx 36 { 37 class GLImplFactory; 38 class ProgramImpl; 39 struct TranslatedAttribute; 40 } // namespace rx 41 42 namespace gl 43 { 44 class Buffer; 45 class BinaryInputStream; 46 class BinaryOutputStream; 47 struct Caps; 48 class Context; 49 struct Extensions; 50 class Framebuffer; 51 class InfoLog; 52 class Shader; 53 class ShaderProgramManager; 54 class State; 55 struct UnusedUniform; 56 struct Version; 57 58 extern const char *const g_fakepath; 59 60 enum class LinkMismatchError 61 { 62 // Shared 63 NO_MISMATCH, 64 TYPE_MISMATCH, 65 ARRAY_SIZE_MISMATCH, 66 PRECISION_MISMATCH, 67 STRUCT_NAME_MISMATCH, 68 FIELD_NUMBER_MISMATCH, 69 FIELD_NAME_MISMATCH, 70 71 // Varying specific 72 INTERPOLATION_TYPE_MISMATCH, 73 INVARIANCE_MISMATCH, 74 75 // Uniform specific 76 BINDING_MISMATCH, 77 LOCATION_MISMATCH, 78 OFFSET_MISMATCH, 79 INSTANCE_NAME_MISMATCH, 80 81 // Interface block specific 82 LAYOUT_QUALIFIER_MISMATCH, 83 MATRIX_PACKING_MISMATCH 84 }; 85 86 class InfoLog : angle::NonCopyable 87 { 88 public: 89 InfoLog(); 90 ~InfoLog(); 91 92 size_t getLength() const; 93 void getLog(GLsizei bufSize, GLsizei *length, char *infoLog) const; 94 95 void appendSanitized(const char *message); 96 void reset(); 97 98 // This helper class ensures we append a newline after writing a line. 99 class StreamHelper : angle::NonCopyable 100 { 101 public: StreamHelper(StreamHelper && rhs)102 StreamHelper(StreamHelper &&rhs) : mStream(rhs.mStream) { rhs.mStream = nullptr; } 103 104 StreamHelper &operator=(StreamHelper &&rhs) 105 { 106 std::swap(mStream, rhs.mStream); 107 return *this; 108 } 109 ~StreamHelper()110 ~StreamHelper() 111 { 112 // Write newline when destroyed on the stack 113 if (mStream) 114 { 115 (*mStream) << std::endl; 116 } 117 } 118 119 template <typename T> 120 StreamHelper &operator<<(const T &value) 121 { 122 (*mStream) << value; 123 return *this; 124 } 125 126 private: 127 friend class InfoLog; 128 StreamHelper(std::stringstream * stream)129 StreamHelper(std::stringstream *stream) : mStream(stream) { ASSERT(stream); } 130 131 std::stringstream *mStream; 132 }; 133 134 template <typename T> 135 StreamHelper operator<<(const T &value) 136 { 137 ensureInitialized(); 138 StreamHelper helper(mLazyStream.get()); 139 helper << value; 140 return helper; 141 } 142 str()143 std::string str() const { return mLazyStream ? mLazyStream->str() : ""; } 144 145 bool empty() const; 146 147 private: ensureInitialized()148 void ensureInitialized() 149 { 150 if (!mLazyStream) 151 { 152 mLazyStream.reset(new std::stringstream()); 153 } 154 } 155 156 std::unique_ptr<std::stringstream> mLazyStream; 157 }; 158 159 void LogLinkMismatch(InfoLog &infoLog, 160 const std::string &variableName, 161 const char *variableType, 162 LinkMismatchError linkError, 163 const std::string &mismatchedStructOrBlockFieldName, 164 ShaderType shaderType1, 165 ShaderType shaderType2); 166 167 bool IsActiveInterfaceBlock(const sh::InterfaceBlock &interfaceBlock); 168 169 void WriteBlockMemberInfo(BinaryOutputStream *stream, const sh::BlockMemberInfo &var); 170 void LoadBlockMemberInfo(BinaryInputStream *stream, sh::BlockMemberInfo *var); 171 172 // Struct used for correlating uniforms/elements of uniform arrays to handles 173 struct VariableLocation 174 { 175 static constexpr unsigned int kUnused = GL_INVALID_INDEX; 176 177 VariableLocation(); 178 VariableLocation(unsigned int arrayIndex, unsigned int index); 179 180 // If used is false, it means this location is only used to fill an empty space in an array, 181 // and there is no corresponding uniform variable for this location. It can also mean the 182 // uniform was optimized out by the implementation. usedVariableLocation183 bool used() const { return (index != kUnused); } markUnusedVariableLocation184 void markUnused() { index = kUnused; } markIgnoredVariableLocation185 void markIgnored() { ignored = true; } 186 187 bool operator==(const VariableLocation &other) const 188 { 189 return arrayIndex == other.arrayIndex && index == other.index; 190 } 191 192 // "arrayIndex" stores the index of the innermost GLSL array. It's zero for non-arrays. 193 unsigned int arrayIndex; 194 // "index" is an index of the variable. The variable contains the indices for other than the 195 // innermost GLSL arrays. 196 unsigned int index; 197 198 // If this location was bound to an unreferenced uniform. Setting data on this uniform is a 199 // no-op. 200 bool ignored; 201 }; 202 203 // Information about a variable binding. 204 // Currently used by CHROMIUM_path_rendering 205 struct BindingInfo 206 { 207 // The type of binding, for example GL_FLOAT_VEC3. 208 // This can be GL_NONE if the variable is optimized away. 209 GLenum type; 210 211 // This is the name of the variable in 212 // the translated shader program. Note that 213 // this can be empty in the case where the 214 // variable has been optimized away. 215 std::string name; 216 217 // True if the binding is valid, otherwise false. 218 bool valid; 219 }; 220 221 // This small structure encapsulates binding sampler uniforms to active GL textures. 222 struct SamplerBinding 223 { 224 SamplerBinding(TextureType textureTypeIn, 225 SamplerFormat formatIn, 226 size_t elementCount, 227 bool unreferenced); 228 SamplerBinding(const SamplerBinding &other); 229 ~SamplerBinding(); 230 231 // Necessary for retrieving active textures from the GL state. 232 TextureType textureType; 233 234 SamplerFormat format; 235 236 // List of all textures bound to this sampler, of type textureType. 237 std::vector<GLuint> boundTextureUnits; 238 239 // A note if this sampler is an unreferenced uniform. 240 bool unreferenced; 241 }; 242 243 // A varying with tranform feedback enabled. If it's an array, either the whole array or one of its 244 // elements specified by 'arrayIndex' can set to be enabled. 245 struct TransformFeedbackVarying : public sh::Varying 246 { TransformFeedbackVaryingTransformFeedbackVarying247 TransformFeedbackVarying(const sh::Varying &varyingIn, GLuint index) 248 : sh::Varying(varyingIn), arrayIndex(index) 249 { 250 ASSERT(!isArrayOfArrays()); 251 } 252 TransformFeedbackVaryingTransformFeedbackVarying253 TransformFeedbackVarying(const sh::ShaderVariable &field, const sh::Varying &parent) 254 : arrayIndex(GL_INVALID_INDEX) 255 { 256 sh::ShaderVariable *thisVar = this; 257 *thisVar = field; 258 interpolation = parent.interpolation; 259 isInvariant = parent.isInvariant; 260 name = parent.name + "." + name; 261 mappedName = parent.mappedName + "." + mappedName; 262 } 263 nameWithArrayIndexTransformFeedbackVarying264 std::string nameWithArrayIndex() const 265 { 266 std::stringstream fullNameStr; 267 fullNameStr << name; 268 if (arrayIndex != GL_INVALID_INDEX) 269 { 270 fullNameStr << "[" << arrayIndex << "]"; 271 } 272 return fullNameStr.str(); 273 } sizeTransformFeedbackVarying274 GLsizei size() const 275 { 276 return (isArray() && arrayIndex == GL_INVALID_INDEX ? getOutermostArraySize() : 1); 277 } 278 279 GLuint arrayIndex; 280 }; 281 282 struct ImageBinding 283 { 284 ImageBinding(size_t count); 285 ImageBinding(GLuint imageUnit, size_t count, bool unreferenced); 286 ImageBinding(const ImageBinding &other); 287 ~ImageBinding(); 288 289 std::vector<GLuint> boundImageUnits; 290 291 // A note if this image unit is an unreferenced uniform. 292 bool unreferenced; 293 }; 294 295 class ProgramState final : angle::NonCopyable 296 { 297 public: 298 ProgramState(); 299 ~ProgramState(); 300 301 const std::string &getLabel(); 302 303 Shader *getAttachedShader(ShaderType shaderType) const; getAttachedShaders()304 const gl::ShaderMap<Shader *> &getAttachedShaders() const { return mAttachedShaders; } getTransformFeedbackVaryingNames()305 const std::vector<std::string> &getTransformFeedbackVaryingNames() const 306 { 307 return mTransformFeedbackVaryingNames; 308 } getTransformFeedbackBufferMode()309 GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; } getUniformBlockBinding(GLuint uniformBlockIndex)310 GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const 311 { 312 ASSERT(uniformBlockIndex < mUniformBlocks.size()); 313 return mUniformBlocks[uniformBlockIndex].binding; 314 } getShaderStorageBlockBinding(GLuint blockIndex)315 GLuint getShaderStorageBlockBinding(GLuint blockIndex) const 316 { 317 ASSERT(blockIndex < mShaderStorageBlocks.size()); 318 return mShaderStorageBlocks[blockIndex].binding; 319 } getActiveUniformBlockBindingsMask()320 const UniformBlockBindingMask &getActiveUniformBlockBindingsMask() const 321 { 322 return mActiveUniformBlockBindings; 323 } getAttributes()324 const std::vector<sh::Attribute> &getAttributes() const { return mAttributes; } getActiveAttribLocationsMask()325 const AttributesMask &getActiveAttribLocationsMask() const 326 { 327 return mActiveAttribLocationsMask; 328 } getNonBuiltinAttribLocationsMask()329 const AttributesMask &getNonBuiltinAttribLocationsMask() const { return mAttributesMask; } getMaxActiveAttribLocation()330 unsigned int getMaxActiveAttribLocation() const { return mMaxActiveAttribLocation; } getActiveOutputVariables()331 DrawBufferMask getActiveOutputVariables() const { return mActiveOutputVariables; } getOutputVariables()332 const std::vector<sh::OutputVariable> &getOutputVariables() const { return mOutputVariables; } getOutputLocations()333 const std::vector<VariableLocation> &getOutputLocations() const { return mOutputLocations; } getSecondaryOutputLocations()334 const std::vector<VariableLocation> &getSecondaryOutputLocations() const 335 { 336 return mSecondaryOutputLocations; 337 } getUniforms()338 const std::vector<LinkedUniform> &getUniforms() const { return mUniforms; } getUniformLocations()339 const std::vector<VariableLocation> &getUniformLocations() const { return mUniformLocations; } getUniformBlocks()340 const std::vector<InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; } getShaderStorageBlocks()341 const std::vector<InterfaceBlock> &getShaderStorageBlocks() const 342 { 343 return mShaderStorageBlocks; 344 } getBufferVariables()345 const std::vector<BufferVariable> &getBufferVariables() const { return mBufferVariables; } getSamplerBindings()346 const std::vector<SamplerBinding> &getSamplerBindings() const { return mSamplerBindings; } getImageBindings()347 const std::vector<ImageBinding> &getImageBindings() const { return mImageBindings; } getComputeShaderLocalSize()348 const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; } getSamplerUniformRange()349 const RangeUI &getSamplerUniformRange() const { return mSamplerUniformRange; } getImageUniformRange()350 const RangeUI &getImageUniformRange() const { return mImageUniformRange; } getAtomicCounterUniformRange()351 const RangeUI &getAtomicCounterUniformRange() const { return mAtomicCounterUniformRange; } getAttributesTypeMask()352 const ComponentTypeMask &getAttributesTypeMask() const { return mAttributesTypeMask; } 353 getLinkedTransformFeedbackVaryings()354 const std::vector<TransformFeedbackVarying> &getLinkedTransformFeedbackVaryings() const 355 { 356 return mLinkedTransformFeedbackVaryings; 357 } getTransformFeedbackStrides()358 const std::vector<GLsizei> &getTransformFeedbackStrides() const 359 { 360 return mTransformFeedbackStrides; 361 } getTransformFeedbackBufferCount()362 size_t getTransformFeedbackBufferCount() const { return mTransformFeedbackStrides.size(); } getAtomicCounterBuffers()363 const std::vector<AtomicCounterBuffer> &getAtomicCounterBuffers() const 364 { 365 return mAtomicCounterBuffers; 366 } 367 368 // Count the number of uniform and storage buffer declarations, counting arrays as one. 369 size_t getUniqueUniformBlockCount() const; 370 size_t getUniqueStorageBlockCount() const; 371 372 GLuint getUniformIndexFromName(const std::string &name) const; 373 GLuint getUniformIndexFromLocation(GLint location) const; 374 Optional<GLuint> getSamplerIndex(GLint location) const; 375 bool isSamplerUniformIndex(GLuint index) const; 376 GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const; 377 GLuint getUniformIndexFromSamplerIndex(GLuint samplerIndex) const; 378 bool isImageUniformIndex(GLuint index) const; 379 GLuint getImageIndexFromUniformIndex(GLuint uniformIndex) const; 380 GLuint getUniformIndexFromImageIndex(GLuint imageIndex) const; 381 GLuint getAttributeLocation(const std::string &name) const; 382 383 GLuint getBufferVariableIndexFromName(const std::string &name) const; 384 getNumViews()385 int getNumViews() const { return mNumViews; } usesMultiview()386 bool usesMultiview() const { return mNumViews != -1; } 387 getLinkedShaderStages()388 const ShaderBitSet &getLinkedShaderStages() const { return mLinkedShaderStages; } hasLinkedShaderStage(ShaderType shaderType)389 bool hasLinkedShaderStage(ShaderType shaderType) const 390 { 391 return mLinkedShaderStages[shaderType]; 392 } getLinkedShaderStageCount()393 size_t getLinkedShaderStageCount() const { return mLinkedShaderStages.count(); } isCompute()394 bool isCompute() const { return hasLinkedShaderStage(ShaderType::Compute); } 395 396 bool hasAttachedShader() const; 397 getActiveSamplersMask()398 const ActiveTextureMask &getActiveSamplersMask() const { return mActiveSamplersMask; } getSamplerFormatForTextureUnitIndex(size_t textureUnitIndex)399 SamplerFormat getSamplerFormatForTextureUnitIndex(size_t textureUnitIndex) const 400 { 401 return mActiveSamplerFormats[textureUnitIndex]; 402 } 403 404 private: 405 friend class MemoryProgramCache; 406 friend class Program; 407 408 void updateTransformFeedbackStrides(); 409 void updateActiveSamplers(); 410 void updateActiveImages(); 411 412 // Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'. 413 void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex); 414 415 std::string mLabel; 416 417 sh::WorkGroupSize mComputeShaderLocalSize; 418 419 ShaderMap<Shader *> mAttachedShaders; 420 421 std::vector<std::string> mTransformFeedbackVaryingNames; 422 std::vector<TransformFeedbackVarying> mLinkedTransformFeedbackVaryings; 423 GLenum mTransformFeedbackBufferMode; 424 425 // For faster iteration on the blocks currently being bound. 426 UniformBlockBindingMask mActiveUniformBlockBindings; 427 428 std::vector<sh::Attribute> mAttributes; 429 angle::BitSet<MAX_VERTEX_ATTRIBS> mActiveAttribLocationsMask; 430 unsigned int mMaxActiveAttribLocation; 431 ComponentTypeMask mAttributesTypeMask; 432 // mAttributesMask is identical to mActiveAttribLocationsMask with built-in attributes removed. 433 AttributesMask mAttributesMask; 434 435 // Uniforms are sorted in order: 436 // 1. Non-opaque uniforms 437 // 2. Sampler uniforms 438 // 3. Image uniforms 439 // 4. Atomic counter uniforms 440 // 5. Uniform block uniforms 441 // This makes opaque uniform validation easier, since we don't need a separate list. 442 // For generating the entries and naming them we follow the spec: GLES 3.1 November 2016 section 443 // 7.3.1.1 Naming Active Resources. There's a separate entry for each struct member and each 444 // inner array of an array of arrays. Names and mapped names of uniforms that are arrays include 445 // [0] in the end. This makes implementation of queries simpler. 446 std::vector<LinkedUniform> mUniforms; 447 448 std::vector<VariableLocation> mUniformLocations; 449 std::vector<InterfaceBlock> mUniformBlocks; 450 std::vector<BufferVariable> mBufferVariables; 451 std::vector<InterfaceBlock> mShaderStorageBlocks; 452 std::vector<AtomicCounterBuffer> mAtomicCounterBuffers; 453 RangeUI mSamplerUniformRange; 454 RangeUI mImageUniformRange; 455 RangeUI mAtomicCounterUniformRange; 456 457 // An array of the samplers that are used by the program 458 std::vector<SamplerBinding> mSamplerBindings; 459 460 // An array of the images that are used by the program 461 std::vector<ImageBinding> mImageBindings; 462 463 // Names and mapped names of output variables that are arrays include [0] in the end, similarly 464 // to uniforms. 465 std::vector<sh::OutputVariable> mOutputVariables; 466 std::vector<VariableLocation> mOutputLocations; 467 468 // EXT_blend_func_extended secondary outputs (ones with index 1) in ESSL 3.00 shaders. 469 std::vector<VariableLocation> mSecondaryOutputLocations; 470 471 DrawBufferMask mActiveOutputVariables; 472 473 // Fragment output variable base types: FLOAT, INT, or UINT. Ordered by location. 474 std::vector<GLenum> mOutputVariableTypes; 475 ComponentTypeMask mDrawBufferTypeMask; 476 477 bool mBinaryRetrieveableHint; 478 bool mSeparable; 479 ShaderBitSet mLinkedShaderStages; 480 481 // ANGLE_multiview. 482 int mNumViews; 483 484 // GL_EXT_geometry_shader. 485 PrimitiveMode mGeometryShaderInputPrimitiveType; 486 PrimitiveMode mGeometryShaderOutputPrimitiveType; 487 int mGeometryShaderInvocations; 488 int mGeometryShaderMaxVertices; 489 490 // GL_ANGLE_multi_draw 491 int mDrawIDLocation; 492 493 // GL_ANGLE_base_vertex_base_instance 494 int mBaseVertexLocation; 495 int mBaseInstanceLocation; 496 497 // The size of the data written to each transform feedback buffer per vertex. 498 std::vector<GLsizei> mTransformFeedbackStrides; 499 500 // Cached mask of active samplers and sampler types. 501 ActiveTextureMask mActiveSamplersMask; 502 ActiveTextureArray<uint32_t> mActiveSamplerRefCounts; 503 ActiveTextureArray<TextureType> mActiveSamplerTypes; 504 ActiveTextureArray<SamplerFormat> mActiveSamplerFormats; 505 506 // Cached mask of active images. 507 ActiveTextureMask mActiveImagesMask; 508 }; 509 510 struct ProgramBinding 511 { ProgramBindingProgramBinding512 ProgramBinding() : location(GL_INVALID_INDEX), aliased(false) {} ProgramBindingProgramBinding513 ProgramBinding(GLuint index) : location(index), aliased(false) {} 514 515 GLuint location; 516 // Whether another binding was set that may potentially alias this. 517 bool aliased; 518 }; 519 520 class ProgramBindings final : angle::NonCopyable 521 { 522 public: 523 ProgramBindings(); 524 ~ProgramBindings(); 525 526 void bindLocation(GLuint index, const std::string &name); 527 int getBindingByName(const std::string &name) const; 528 int getBinding(const sh::VariableWithLocation &variable) const; 529 530 using const_iterator = std::unordered_map<std::string, ProgramBinding>::const_iterator; 531 const_iterator begin() const; 532 const_iterator end() const; 533 534 private: 535 std::unordered_map<std::string, ProgramBinding> mBindings; 536 }; 537 538 struct ProgramVaryingRef 539 { getProgramVaryingRef540 const sh::Varying *get() const { return vertex ? vertex : fragment; } 541 542 const sh::Varying *vertex = nullptr; 543 const sh::Varying *fragment = nullptr; 544 }; 545 546 using ProgramMergedVaryings = std::map<std::string, ProgramVaryingRef>; 547 548 class Program final : angle::NonCopyable, public LabeledObject 549 { 550 public: 551 Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLuint handle); 552 void onDestroy(const Context *context); 553 554 GLuint id() const; 555 556 void setLabel(const Context *context, const std::string &label) override; 557 const std::string &getLabel() const override; 558 getImplementation()559 ANGLE_INLINE rx::ProgramImpl *getImplementation() const 560 { 561 ASSERT(mLinkResolved); 562 return mProgram; 563 } 564 565 void attachShader(Shader *shader); 566 void detachShader(const Context *context, Shader *shader); 567 int getAttachedShadersCount() const; 568 569 const Shader *getAttachedShader(ShaderType shaderType) const; 570 571 void bindAttributeLocation(GLuint index, const char *name); 572 void bindUniformLocation(GLuint index, const char *name); 573 574 // CHROMIUM_path_rendering 575 BindingInfo getFragmentInputBindingInfo(GLint index) const; 576 void bindFragmentInputLocation(GLint index, const char *name); 577 void pathFragmentInputGen(GLint index, GLenum genMode, GLint components, const GLfloat *coeffs); 578 579 // EXT_blend_func_extended 580 void bindFragmentOutputLocation(GLuint index, const char *name); 581 void bindFragmentOutputIndex(GLuint index, const char *name); 582 583 // KHR_parallel_shader_compile 584 // Try to link the program asynchrously. As a result, background threads may be launched to 585 // execute the linking tasks concurrently. 586 angle::Result link(const Context *context); 587 588 // Peek whether there is any running linking tasks. 589 bool isLinking() const; 590 isLinked()591 bool isLinked() const 592 { 593 ASSERT(mLinkResolved); 594 return mLinked; 595 } 596 hasLinkedShaderStage(ShaderType shaderType)597 bool hasLinkedShaderStage(ShaderType shaderType) const 598 { 599 ASSERT(shaderType != ShaderType::InvalidEnum); 600 return mState.hasLinkedShaderStage(shaderType); 601 } isCompute()602 bool isCompute() const { return mState.isCompute(); } 603 604 angle::Result loadBinary(const Context *context, 605 GLenum binaryFormat, 606 const void *binary, 607 GLsizei length); 608 angle::Result saveBinary(Context *context, 609 GLenum *binaryFormat, 610 void *binary, 611 GLsizei bufSize, 612 GLsizei *length) const; 613 GLint getBinaryLength(Context *context) const; 614 void setBinaryRetrievableHint(bool retrievable); 615 bool getBinaryRetrievableHint() const; 616 617 void setSeparable(bool separable); 618 bool isSeparable() const; 619 620 int getInfoLogLength() const; 621 void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const; 622 void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders) const; 623 624 GLuint getAttributeLocation(const std::string &name) const; 625 bool isAttribLocationActive(size_t attribLocation) const; 626 627 void getActiveAttribute(GLuint index, 628 GLsizei bufsize, 629 GLsizei *length, 630 GLint *size, 631 GLenum *type, 632 GLchar *name) const; 633 GLint getActiveAttributeCount() const; 634 GLint getActiveAttributeMaxLength() const; 635 const std::vector<sh::Attribute> &getAttributes() const; 636 637 GLint getFragDataLocation(const std::string &name) const; 638 size_t getOutputResourceCount() const; 639 const std::vector<GLenum> &getOutputVariableTypes() const; getActiveOutputVariables()640 DrawBufferMask getActiveOutputVariables() const 641 { 642 ASSERT(mLinkResolved); 643 return mState.mActiveOutputVariables; 644 } 645 646 // EXT_blend_func_extended 647 GLint getFragDataIndex(const std::string &name) const; 648 649 void getActiveUniform(GLuint index, 650 GLsizei bufsize, 651 GLsizei *length, 652 GLint *size, 653 GLenum *type, 654 GLchar *name) const; 655 GLint getActiveUniformCount() const; 656 size_t getActiveBufferVariableCount() const; 657 GLint getActiveUniformMaxLength() const; 658 bool isValidUniformLocation(GLint location) const; 659 const LinkedUniform &getUniformByLocation(GLint location) const; 660 const VariableLocation &getUniformLocation(GLint location) const; 661 getUniformLocations()662 const std::vector<VariableLocation> &getUniformLocations() const 663 { 664 ASSERT(mLinkResolved); 665 return mState.mUniformLocations; 666 } 667 getUniformByIndex(GLuint index)668 const LinkedUniform &getUniformByIndex(GLuint index) const 669 { 670 ASSERT(mLinkResolved); 671 ASSERT(index < static_cast<size_t>(mState.mUniforms.size())); 672 return mState.mUniforms[index]; 673 } 674 675 const BufferVariable &getBufferVariableByIndex(GLuint index) const; 676 677 enum SetUniformResult 678 { 679 SamplerChanged, 680 NoSamplerChange, 681 }; 682 683 GLint getUniformLocation(const std::string &name) const; 684 GLuint getUniformIndex(const std::string &name) const; 685 void setUniform1fv(GLint location, GLsizei count, const GLfloat *v); 686 void setUniform2fv(GLint location, GLsizei count, const GLfloat *v); 687 void setUniform3fv(GLint location, GLsizei count, const GLfloat *v); 688 void setUniform4fv(GLint location, GLsizei count, const GLfloat *v); 689 void setUniform1iv(Context *context, GLint location, GLsizei count, const GLint *v); 690 void setUniform2iv(GLint location, GLsizei count, const GLint *v); 691 void setUniform3iv(GLint location, GLsizei count, const GLint *v); 692 void setUniform4iv(GLint location, GLsizei count, const GLint *v); 693 void setUniform1uiv(GLint location, GLsizei count, const GLuint *v); 694 void setUniform2uiv(GLint location, GLsizei count, const GLuint *v); 695 void setUniform3uiv(GLint location, GLsizei count, const GLuint *v); 696 void setUniform4uiv(GLint location, GLsizei count, const GLuint *v); 697 void setUniformMatrix2fv(GLint location, 698 GLsizei count, 699 GLboolean transpose, 700 const GLfloat *value); 701 void setUniformMatrix3fv(GLint location, 702 GLsizei count, 703 GLboolean transpose, 704 const GLfloat *value); 705 void setUniformMatrix4fv(GLint location, 706 GLsizei count, 707 GLboolean transpose, 708 const GLfloat *value); 709 void setUniformMatrix2x3fv(GLint location, 710 GLsizei count, 711 GLboolean transpose, 712 const GLfloat *value); 713 void setUniformMatrix3x2fv(GLint location, 714 GLsizei count, 715 GLboolean transpose, 716 const GLfloat *value); 717 void setUniformMatrix2x4fv(GLint location, 718 GLsizei count, 719 GLboolean transpose, 720 const GLfloat *value); 721 void setUniformMatrix4x2fv(GLint location, 722 GLsizei count, 723 GLboolean transpose, 724 const GLfloat *value); 725 void setUniformMatrix3x4fv(GLint location, 726 GLsizei count, 727 GLboolean transpose, 728 const GLfloat *value); 729 void setUniformMatrix4x3fv(GLint location, 730 GLsizei count, 731 GLboolean transpose, 732 const GLfloat *value); 733 734 void getUniformfv(const Context *context, GLint location, GLfloat *params) const; 735 void getUniformiv(const Context *context, GLint location, GLint *params) const; 736 void getUniformuiv(const Context *context, GLint location, GLuint *params) const; 737 738 void getActiveUniformBlockName(const GLuint blockIndex, 739 GLsizei bufSize, 740 GLsizei *length, 741 GLchar *blockName) const; 742 void getActiveShaderStorageBlockName(const GLuint blockIndex, 743 GLsizei bufSize, 744 GLsizei *length, 745 GLchar *blockName) const; 746 getActiveUniformBlockCount()747 ANGLE_INLINE GLuint getActiveUniformBlockCount() const 748 { 749 ASSERT(mLinkResolved); 750 return static_cast<GLuint>(mState.mUniformBlocks.size()); 751 } 752 getActiveAtomicCounterBufferCount()753 ANGLE_INLINE GLuint getActiveAtomicCounterBufferCount() const 754 { 755 ASSERT(mLinkResolved); 756 return static_cast<GLuint>(mState.mAtomicCounterBuffers.size()); 757 } 758 getActiveShaderStorageBlockCount()759 ANGLE_INLINE GLuint getActiveShaderStorageBlockCount() const 760 { 761 ASSERT(mLinkResolved); 762 return static_cast<GLuint>(mState.mShaderStorageBlocks.size()); 763 } 764 765 GLint getActiveUniformBlockMaxNameLength() const; 766 GLint getActiveShaderStorageBlockMaxNameLength() const; 767 768 GLuint getUniformBlockIndex(const std::string &name) const; 769 GLuint getShaderStorageBlockIndex(const std::string &name) const; 770 771 void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding); 772 GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const; 773 GLuint getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const; 774 775 const InterfaceBlock &getUniformBlockByIndex(GLuint index) const; 776 const InterfaceBlock &getShaderStorageBlockByIndex(GLuint index) const; 777 778 void setTransformFeedbackVaryings(GLsizei count, 779 const GLchar *const *varyings, 780 GLenum bufferMode); 781 void getTransformFeedbackVarying(GLuint index, 782 GLsizei bufSize, 783 GLsizei *length, 784 GLsizei *size, 785 GLenum *type, 786 GLchar *name) const; 787 GLsizei getTransformFeedbackVaryingCount() const; 788 GLsizei getTransformFeedbackVaryingMaxLength() const; 789 GLenum getTransformFeedbackBufferMode() const; 790 GLuint getTransformFeedbackVaryingResourceIndex(const GLchar *name) const; 791 const TransformFeedbackVarying &getTransformFeedbackVaryingResource(GLuint index) const; 792 793 bool hasDrawIDUniform() const; 794 void setDrawIDUniform(GLint drawid); 795 796 bool hasBaseVertexUniform() const; 797 void setBaseVertexUniform(GLint baseVertex); 798 bool hasBaseInstanceUniform() const; 799 void setBaseInstanceUniform(GLuint baseInstance); 800 addRef()801 ANGLE_INLINE void addRef() 802 { 803 ASSERT(mLinkResolved); 804 mRefCount++; 805 } 806 release(const Context * context)807 ANGLE_INLINE void release(const Context *context) 808 { 809 ASSERT(mLinkResolved); 810 mRefCount--; 811 812 if (mRefCount == 0 && mDeleteStatus) 813 { 814 deleteSelf(context); 815 } 816 } 817 818 unsigned int getRefCount() const; isInUse()819 bool isInUse() const { return getRefCount() != 0; } 820 void flagForDeletion(); 821 bool isFlaggedForDeletion() const; 822 823 void validate(const Caps &caps); validateSamplers(InfoLog * infoLog,const Caps & caps)824 bool validateSamplers(InfoLog *infoLog, const Caps &caps) 825 { 826 // Skip cache if we're using an infolog, so we get the full error. 827 // Also skip the cache if the sample mapping has changed, or if we haven't ever validated. 828 if (infoLog == nullptr && mCachedValidateSamplersResult.valid()) 829 { 830 return mCachedValidateSamplersResult.value(); 831 } 832 833 return validateSamplersImpl(infoLog, caps); 834 } 835 836 bool isValidated() const; 837 getActiveAttribLocationsMask()838 const AttributesMask &getActiveAttribLocationsMask() const 839 { 840 ASSERT(mLinkResolved); 841 return mState.mActiveAttribLocationsMask; 842 } 843 844 const std::vector<SamplerBinding> &getSamplerBindings() const; getImageBindings()845 const std::vector<ImageBinding> &getImageBindings() const 846 { 847 ASSERT(mLinkResolved); 848 return mState.mImageBindings; 849 } 850 const sh::WorkGroupSize &getComputeShaderLocalSize() const; 851 PrimitiveMode getGeometryShaderInputPrimitiveType() const; 852 PrimitiveMode getGeometryShaderOutputPrimitiveType() const; 853 GLint getGeometryShaderInvocations() const; 854 GLint getGeometryShaderMaxVertices() const; 855 getState()856 const ProgramState &getState() const 857 { 858 ASSERT(mLinkResolved); 859 return mState; 860 } 861 862 static LinkMismatchError LinkValidateVariablesBase( 863 const sh::ShaderVariable &variable1, 864 const sh::ShaderVariable &variable2, 865 bool validatePrecision, 866 bool validateArraySize, 867 std::string *mismatchedStructOrBlockMemberName); 868 869 GLuint getInputResourceIndex(const GLchar *name) const; 870 GLuint getOutputResourceIndex(const GLchar *name) const; 871 void getInputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; 872 void getOutputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; 873 void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; 874 void getBufferVariableResourceName(GLuint index, 875 GLsizei bufSize, 876 GLsizei *length, 877 GLchar *name) const; 878 const sh::Attribute &getInputResource(GLuint index) const; 879 const sh::OutputVariable &getOutputResource(GLuint index) const; 880 881 const ProgramBindings &getAttributeBindings() const; 882 const ProgramBindings &getUniformLocationBindings() const; 883 const ProgramBindings &getFragmentInputBindings() const; 884 getNumViews()885 int getNumViews() const 886 { 887 ASSERT(mLinkResolved); 888 return mState.getNumViews(); 889 } 890 usesMultiview()891 bool usesMultiview() const { return mState.usesMultiview(); } 892 893 ComponentTypeMask getDrawBufferTypeMask() const; 894 ComponentTypeMask getAttributesTypeMask() const; 895 AttributesMask getAttributesMask() const; 896 897 const std::vector<GLsizei> &getTransformFeedbackStrides() const; 898 getActiveSamplersMask()899 const ActiveTextureMask &getActiveSamplersMask() const { return mState.mActiveSamplersMask; } getActiveImagesMask()900 const ActiveTextureMask &getActiveImagesMask() const { return mState.mActiveImagesMask; } 901 getActiveSamplerTypes()902 const ActiveTextureArray<TextureType> &getActiveSamplerTypes() const 903 { 904 return mState.mActiveSamplerTypes; 905 } 906 907 // Program dirty bits. 908 enum DirtyBitType 909 { 910 DIRTY_BIT_UNIFORM_BLOCK_BINDING_0, 911 DIRTY_BIT_UNIFORM_BLOCK_BINDING_MAX = 912 DIRTY_BIT_UNIFORM_BLOCK_BINDING_0 + IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS, 913 914 DIRTY_BIT_COUNT = DIRTY_BIT_UNIFORM_BLOCK_BINDING_MAX, 915 }; 916 917 using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>; 918 919 angle::Result syncState(const Context *context); 920 921 // Try to resolve linking. Inlined to make sure its overhead is as low as possible. resolveLink(const Context * context)922 void resolveLink(const Context *context) 923 { 924 if (!mLinkResolved) 925 { 926 resolveLinkImpl(context); 927 } 928 } 929 hasAnyDirtyBit()930 ANGLE_INLINE bool hasAnyDirtyBit() const { return mDirtyBits.any(); } 931 932 // Writes a program's binary to the output memory buffer. 933 void serialize(const Context *context, angle::MemoryBuffer *binaryOut) const; 934 935 private: 936 struct LinkingState; 937 938 ~Program() override; 939 940 // Loads program state according to the specified binary blob. 941 angle::Result deserialize(const Context *context, BinaryInputStream &stream, InfoLog &infoLog); 942 943 void unlink(); 944 void deleteSelf(const Context *context); 945 946 bool linkValidateShaders(InfoLog &infoLog); 947 bool linkAttributes(const Context *context, InfoLog &infoLog); 948 bool linkInterfaceBlocks(const Caps &caps, 949 const Version &version, 950 bool webglCompatibility, 951 InfoLog &infoLog, 952 GLuint *combinedShaderStorageBlocksCount); 953 bool linkVaryings(InfoLog &infoLog) const; 954 955 bool linkUniforms(const Caps &caps, 956 InfoLog &infoLog, 957 const ProgramBindings &uniformLocationBindings, 958 GLuint *combinedImageUniformsCount, 959 std::vector<UnusedUniform> *unusedUniforms); 960 void linkSamplerAndImageBindings(GLuint *combinedImageUniformsCount); 961 bool linkAtomicCounterBuffers(); 962 963 void updateLinkedShaderStages(); 964 965 static LinkMismatchError LinkValidateVaryings(const sh::Varying &outputVarying, 966 const sh::Varying &inputVarying, 967 int shaderVersion, 968 bool validateGeometryShaderInputVarying, 969 std::string *mismatchedStructFieldName); 970 971 bool linkValidateShaderInterfaceMatching(Shader *generatingShader, 972 Shader *consumingShader, 973 InfoLog &infoLog) const; 974 975 // Check for aliased path rendering input bindings (if any). 976 // If more than one binding refer statically to the same location the link must fail. 977 bool linkValidateFragmentInputBindings(InfoLog &infoLog) const; 978 979 bool linkValidateBuiltInVaryings(InfoLog &infoLog) const; 980 bool linkValidateTransformFeedback(const Version &version, 981 InfoLog &infoLog, 982 const ProgramMergedVaryings &linkedVaryings, 983 const Caps &caps) const; 984 bool linkValidateGlobalNames(InfoLog &infoLog) const; 985 986 void gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyings); 987 988 ProgramMergedVaryings getMergedVaryings() const; 989 int getOutputLocationForLink(const sh::OutputVariable &outputVariable) const; 990 bool isOutputSecondaryForLink(const sh::OutputVariable &outputVariable) const; 991 bool linkOutputVariables(const Caps &caps, 992 const Extensions &extensions, 993 const Version &version, 994 GLuint combinedImageUniformsCount, 995 GLuint combinedShaderStorageBlocksCount); 996 997 void setUniformValuesFromBindingQualifiers(); 998 999 void initInterfaceBlockBindings(); 1000 1001 // Both these function update the cached uniform values and return a modified "count" 1002 // so that the uniform update doesn't overflow the uniform. 1003 template <typename T> 1004 GLsizei clampUniformCount(const VariableLocation &locationInfo, 1005 GLsizei count, 1006 int vectorSize, 1007 const T *v); 1008 template <size_t cols, size_t rows, typename T> 1009 GLsizei clampMatrixUniformCount(GLint location, GLsizei count, GLboolean transpose, const T *v); 1010 1011 void updateSamplerUniform(Context *context, 1012 const VariableLocation &locationInfo, 1013 GLsizei clampedCount, 1014 const GLint *v); 1015 1016 template <typename DestT> 1017 void getUniformInternal(const Context *context, 1018 DestT *dataOut, 1019 GLint location, 1020 GLenum nativeType, 1021 int components) const; 1022 1023 template <typename T> 1024 void getResourceName(GLuint index, 1025 const std::vector<T> &resources, 1026 GLsizei bufSize, 1027 GLsizei *length, 1028 GLchar *name) const; 1029 1030 template <typename T> 1031 GLint getActiveInterfaceBlockMaxNameLength(const std::vector<T> &resources) const; 1032 1033 GLuint getSamplerUniformBinding(const VariableLocation &uniformLocation) const; 1034 1035 bool validateSamplersImpl(InfoLog *infoLog, const Caps &caps); 1036 1037 // Block until linking is finished and resolve it. 1038 void resolveLinkImpl(const gl::Context *context); 1039 1040 void postResolveLink(const gl::Context *context); 1041 1042 ProgramState mState; 1043 rx::ProgramImpl *mProgram; 1044 1045 bool mValidated; 1046 1047 ProgramBindings mAttributeBindings; 1048 1049 // Note that this has nothing to do with binding layout qualifiers that can be set for some 1050 // uniforms in GLES3.1+. It is used to pre-set the location of uniforms. 1051 ProgramBindings mUniformLocationBindings; 1052 1053 // CHROMIUM_path_rendering 1054 ProgramBindings mFragmentInputBindings; 1055 1056 // EXT_blend_func_extended 1057 ProgramBindings mFragmentOutputLocations; 1058 ProgramBindings mFragmentOutputIndexes; 1059 1060 bool mLinked; 1061 bool mLinkResolved; 1062 std::unique_ptr<LinkingState> mLinkingState; 1063 bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use 1064 1065 unsigned int mRefCount; 1066 1067 ShaderProgramManager *mResourceManager; 1068 const GLuint mHandle; 1069 1070 InfoLog mInfoLog; 1071 1072 // Cache for sampler validation 1073 Optional<bool> mCachedValidateSamplersResult; 1074 1075 DirtyBits mDirtyBits; 1076 }; 1077 } // namespace gl 1078 1079 #endif // LIBANGLE_PROGRAM_H_ 1080