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/InfoLog.h" 32 #include "libANGLE/ProgramExecutable.h" 33 #include "libANGLE/ProgramLinkedResources.h" 34 #include "libANGLE/RefCountObject.h" 35 #include "libANGLE/Uniform.h" 36 #include "libANGLE/angletypes.h" 37 38 namespace rx 39 { 40 class GLImplFactory; 41 class ProgramImpl; 42 struct TranslatedAttribute; 43 } // namespace rx 44 45 namespace gl 46 { 47 class Buffer; 48 class BinaryInputStream; 49 class BinaryOutputStream; 50 struct Caps; 51 class Context; 52 struct Extensions; 53 class Framebuffer; 54 class ProgramExecutable; 55 class Shader; 56 class ShaderProgramManager; 57 class State; 58 struct UnusedUniform; 59 struct Version; 60 61 extern const char *const g_fakepath; 62 63 enum class LinkMismatchError 64 { 65 // Shared 66 NO_MISMATCH, 67 TYPE_MISMATCH, 68 ARRAY_SIZE_MISMATCH, 69 PRECISION_MISMATCH, 70 STRUCT_NAME_MISMATCH, 71 FIELD_NUMBER_MISMATCH, 72 FIELD_NAME_MISMATCH, 73 74 // Varying specific 75 INTERPOLATION_TYPE_MISMATCH, 76 INVARIANCE_MISMATCH, 77 78 // Uniform specific 79 BINDING_MISMATCH, 80 LOCATION_MISMATCH, 81 OFFSET_MISMATCH, 82 INSTANCE_NAME_MISMATCH, 83 FORMAT_MISMATCH, 84 85 // Interface block specific 86 LAYOUT_QUALIFIER_MISMATCH, 87 MATRIX_PACKING_MISMATCH, 88 }; 89 90 void LogLinkMismatch(InfoLog &infoLog, 91 const std::string &variableName, 92 const char *variableType, 93 LinkMismatchError linkError, 94 const std::string &mismatchedStructOrBlockFieldName, 95 ShaderType shaderType1, 96 ShaderType shaderType2); 97 98 bool IsActiveInterfaceBlock(const sh::InterfaceBlock &interfaceBlock); 99 100 void WriteBlockMemberInfo(BinaryOutputStream *stream, const sh::BlockMemberInfo &var); 101 void LoadBlockMemberInfo(BinaryInputStream *stream, sh::BlockMemberInfo *var); 102 103 void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var); 104 void LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var); 105 106 // Struct used for correlating uniforms/elements of uniform arrays to handles 107 struct VariableLocation 108 { 109 static constexpr unsigned int kUnused = GL_INVALID_INDEX; 110 111 VariableLocation(); 112 VariableLocation(unsigned int arrayIndex, unsigned int index); 113 114 // If used is false, it means this location is only used to fill an empty space in an array, 115 // and there is no corresponding uniform variable for this location. It can also mean the 116 // uniform was optimized out by the implementation. usedVariableLocation117 bool used() const { return (index != kUnused); } markUnusedVariableLocation118 void markUnused() { index = kUnused; } markIgnoredVariableLocation119 void markIgnored() { ignored = true; } 120 121 bool operator==(const VariableLocation &other) const 122 { 123 return arrayIndex == other.arrayIndex && index == other.index; 124 } 125 126 // "arrayIndex" stores the index of the innermost GLSL array. It's zero for non-arrays. 127 unsigned int arrayIndex; 128 // "index" is an index of the variable. The variable contains the indices for other than the 129 // innermost GLSL arrays. 130 unsigned int index; 131 132 // If this location was bound to an unreferenced uniform. Setting data on this uniform is a 133 // no-op. 134 bool ignored; 135 }; 136 137 // Information about a variable binding. 138 // Currently used by CHROMIUM_path_rendering 139 struct BindingInfo 140 { 141 // The type of binding, for example GL_FLOAT_VEC3. 142 // This can be GL_NONE if the variable is optimized away. 143 GLenum type; 144 145 // This is the name of the variable in 146 // the translated shader program. Note that 147 // this can be empty in the case where the 148 // variable has been optimized away. 149 std::string name; 150 151 // True if the binding is valid, otherwise false. 152 bool valid; 153 }; 154 155 struct ProgramBinding 156 { ProgramBindingProgramBinding157 ProgramBinding() : location(GL_INVALID_INDEX), aliased(false) {} ProgramBindingProgramBinding158 ProgramBinding(GLuint index) : location(index), aliased(false) {} 159 160 GLuint location; 161 // Whether another binding was set that may potentially alias this. 162 bool aliased; 163 }; 164 165 class ProgramBindings final : angle::NonCopyable 166 { 167 public: 168 ProgramBindings(); 169 ~ProgramBindings(); 170 171 void bindLocation(GLuint index, const std::string &name); 172 int getBindingByName(const std::string &name) const; 173 int getBinding(const sh::ShaderVariable &variable) const; 174 175 using const_iterator = std::unordered_map<std::string, GLuint>::const_iterator; 176 const_iterator begin() const; 177 const_iterator end() const; 178 179 private: 180 std::unordered_map<std::string, GLuint> mBindings; 181 }; 182 183 // Uniforms and Fragment Outputs require special treatment due to array notation (e.g., "[0]") 184 class ProgramAliasedBindings final : angle::NonCopyable 185 { 186 public: 187 ProgramAliasedBindings(); 188 ~ProgramAliasedBindings(); 189 190 void bindLocation(GLuint index, const std::string &name); 191 int getBindingByName(const std::string &name) const; 192 int getBindingByLocation(GLuint location) const; 193 int getBinding(const sh::ShaderVariable &variable) const; 194 195 using const_iterator = std::unordered_map<std::string, ProgramBinding>::const_iterator; 196 const_iterator begin() const; 197 const_iterator end() const; 198 199 private: 200 std::unordered_map<std::string, ProgramBinding> mBindings; 201 }; 202 203 class ProgramState final : angle::NonCopyable 204 { 205 public: 206 ProgramState(); 207 ~ProgramState(); 208 209 const std::string &getLabel(); 210 211 Shader *getAttachedShader(ShaderType shaderType) const; getAttachedShaders()212 const gl::ShaderMap<Shader *> &getAttachedShaders() const { return mAttachedShaders; } getTransformFeedbackVaryingNames()213 const std::vector<std::string> &getTransformFeedbackVaryingNames() const 214 { 215 return mTransformFeedbackVaryingNames; 216 } getTransformFeedbackBufferMode()217 GLint getTransformFeedbackBufferMode() const 218 { 219 return mExecutable->getTransformFeedbackBufferMode(); 220 } getUniformBlockBinding(GLuint uniformBlockIndex)221 GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const 222 { 223 return mExecutable->getUniformBlockBinding(uniformBlockIndex); 224 } getShaderStorageBlockBinding(GLuint blockIndex)225 GLuint getShaderStorageBlockBinding(GLuint blockIndex) const 226 { 227 return mExecutable->getShaderStorageBlockBinding(blockIndex); 228 } getActiveUniformBlockBindingsMask()229 const UniformBlockBindingMask &getActiveUniformBlockBindingsMask() const 230 { 231 return mActiveUniformBlockBindings; 232 } getProgramInputs()233 const std::vector<sh::ShaderVariable> &getProgramInputs() const 234 { 235 return mExecutable->getProgramInputs(); 236 } getActiveOutputVariables()237 DrawBufferMask getActiveOutputVariables() const { return mActiveOutputVariables; } getOutputVariables()238 const std::vector<sh::ShaderVariable> &getOutputVariables() const 239 { 240 return mExecutable->getOutputVariables(); 241 } getOutputLocations()242 const std::vector<VariableLocation> &getOutputLocations() const 243 { 244 return mExecutable->getOutputLocations(); 245 } getSecondaryOutputLocations()246 const std::vector<VariableLocation> &getSecondaryOutputLocations() const 247 { 248 return mSecondaryOutputLocations; 249 } getUniforms()250 const std::vector<LinkedUniform> &getUniforms() const { return mExecutable->getUniforms(); } getUniformLocations()251 const std::vector<VariableLocation> &getUniformLocations() const { return mUniformLocations; } getUniformBlocks()252 const std::vector<InterfaceBlock> &getUniformBlocks() const 253 { 254 return mExecutable->getUniformBlocks(); 255 } getShaderStorageBlocks()256 const std::vector<InterfaceBlock> &getShaderStorageBlocks() const 257 { 258 return mExecutable->getShaderStorageBlocks(); 259 } getBufferVariables()260 const std::vector<BufferVariable> &getBufferVariables() const { return mBufferVariables; } getSamplerBindings()261 const std::vector<SamplerBinding> &getSamplerBindings() const { return mSamplerBindings; } getImageBindings()262 const std::vector<ImageBinding> &getImageBindings() const { return mImageBindings; } getComputeShaderLocalSize()263 const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; } getDefaultUniformRange()264 const RangeUI &getDefaultUniformRange() const { return mDefaultUniformRange; } getSamplerUniformRange()265 const RangeUI &getSamplerUniformRange() const { return mExecutable->getSamplerUniformRange(); } getImageUniformRange()266 const RangeUI &getImageUniformRange() const { return mExecutable->getImageUniformRange(); } getAtomicCounterUniformRange()267 const RangeUI &getAtomicCounterUniformRange() const { return mAtomicCounterUniformRange; } 268 getLinkedTransformFeedbackVaryings()269 const std::vector<TransformFeedbackVarying> &getLinkedTransformFeedbackVaryings() const 270 { 271 return mExecutable->getLinkedTransformFeedbackVaryings(); 272 } getTransformFeedbackStrides()273 const std::vector<GLsizei> &getTransformFeedbackStrides() const 274 { 275 return mExecutable->getTransformFeedbackStrides(); 276 } getAtomicCounterBuffers()277 const std::vector<AtomicCounterBuffer> &getAtomicCounterBuffers() const 278 { 279 return mExecutable->getAtomicCounterBuffers(); 280 } 281 282 GLuint getUniformIndexFromName(const std::string &name) const; 283 GLuint getUniformIndexFromLocation(UniformLocation location) const; 284 Optional<GLuint> getSamplerIndex(UniformLocation location) const; 285 bool isSamplerUniformIndex(GLuint index) const; 286 GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const; 287 GLuint getUniformIndexFromSamplerIndex(GLuint samplerIndex) const; 288 bool isImageUniformIndex(GLuint index) const; 289 GLuint getImageIndexFromUniformIndex(GLuint uniformIndex) const; 290 GLuint getUniformIndexFromImageIndex(GLuint imageIndex) const; 291 GLuint getAttributeLocation(const std::string &name) const; 292 293 GLuint getBufferVariableIndexFromName(const std::string &name) const; 294 getNumViews()295 int getNumViews() const { return mNumViews; } usesMultiview()296 bool usesMultiview() const { return mNumViews != -1; } 297 298 bool hasAttachedShader() const; 299 300 ShaderType getFirstAttachedShaderStageType() const; 301 ShaderType getLastAttachedShaderStageType() const; 302 getUniformLocationBindings()303 const ProgramAliasedBindings &getUniformLocationBindings() const 304 { 305 return mUniformLocationBindings; 306 } 307 getExecutable()308 const ProgramExecutable &getExecutable() const 309 { 310 ASSERT(mExecutable); 311 return *mExecutable; 312 } getExecutable()313 ProgramExecutable &getExecutable() 314 { 315 ASSERT(mExecutable); 316 return *mExecutable; 317 } 318 hasDefaultUniforms()319 bool hasDefaultUniforms() const { return !getDefaultUniformRange().empty(); } hasTextures()320 bool hasTextures() const { return !getSamplerBindings().empty(); } hasImages()321 bool hasImages() const { return !getImageBindings().empty(); } hasEarlyFragmentTestsOptimization()322 bool hasEarlyFragmentTestsOptimization() const { return mEarlyFramentTestsOptimization; } 323 isShaderMarkedForDetach(gl::ShaderType shaderType)324 bool isShaderMarkedForDetach(gl::ShaderType shaderType) const 325 { 326 return mAttachedShadersMarkedForDetach[shaderType]; 327 } 328 329 // A Program can only either be graphics or compute, but never both, so it 330 // can answer isCompute() based on which shaders it has. isCompute()331 bool isCompute() const { return mExecutable->hasLinkedShaderStage(ShaderType::Compute); } 332 333 private: 334 friend class MemoryProgramCache; 335 friend class Program; 336 337 void updateTransformFeedbackStrides(); 338 void updateActiveSamplers(); 339 void updateActiveImages(); 340 void updateProgramInterfaceInputs(); 341 void updateProgramInterfaceOutputs(); 342 343 // Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'. 344 void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex); 345 346 std::string mLabel; 347 348 sh::WorkGroupSize mComputeShaderLocalSize; 349 350 ShaderMap<Shader *> mAttachedShaders; 351 ShaderMap<bool> mAttachedShadersMarkedForDetach; 352 353 uint32_t mLocationsUsedForXfbExtension; 354 std::vector<std::string> mTransformFeedbackVaryingNames; 355 356 // For faster iteration on the blocks currently being bound. 357 UniformBlockBindingMask mActiveUniformBlockBindings; 358 359 std::vector<VariableLocation> mUniformLocations; 360 std::vector<BufferVariable> mBufferVariables; 361 RangeUI mDefaultUniformRange; 362 RangeUI mAtomicCounterUniformRange; 363 364 // An array of the samplers that are used by the program 365 std::vector<SamplerBinding> mSamplerBindings; 366 367 // An array of the images that are used by the program 368 std::vector<ImageBinding> mImageBindings; 369 370 // EXT_blend_func_extended secondary outputs (ones with index 1) in ESSL 3.00 shaders. 371 std::vector<VariableLocation> mSecondaryOutputLocations; 372 373 DrawBufferMask mActiveOutputVariables; 374 375 // Fragment output variable base types: FLOAT, INT, or UINT. Ordered by location. 376 std::vector<GLenum> mOutputVariableTypes; 377 ComponentTypeMask mDrawBufferTypeMask; 378 379 bool mBinaryRetrieveableHint; 380 bool mSeparable; 381 bool mEarlyFramentTestsOptimization; 382 383 // ANGLE_multiview. 384 int mNumViews; 385 386 // GL_EXT_geometry_shader. 387 PrimitiveMode mGeometryShaderInputPrimitiveType; 388 PrimitiveMode mGeometryShaderOutputPrimitiveType; 389 int mGeometryShaderInvocations; 390 int mGeometryShaderMaxVertices; 391 392 // GL_ANGLE_multi_draw 393 int mDrawIDLocation; 394 395 // GL_ANGLE_base_vertex_base_instance 396 int mBaseVertexLocation; 397 int mBaseInstanceLocation; 398 // Cached value of base vertex and base instance 399 // need to reset them to zero if using non base vertex or base instance draw calls. 400 GLint mCachedBaseVertex; 401 GLuint mCachedBaseInstance; 402 403 // Note that this has nothing to do with binding layout qualifiers that can be set for some 404 // uniforms in GLES3.1+. It is used to pre-set the location of uniforms. 405 ProgramAliasedBindings mUniformLocationBindings; 406 407 std::shared_ptr<ProgramExecutable> mExecutable; 408 }; 409 410 struct ProgramVaryingRef 411 { getProgramVaryingRef412 const sh::ShaderVariable *get(ShaderType stage) const 413 { 414 ASSERT(stage == frontShaderStage || stage == backShaderStage); 415 const sh::ShaderVariable *ref = stage == frontShaderStage ? frontShader : backShader; 416 ASSERT(ref); 417 return ref; 418 } 419 420 const sh::ShaderVariable *frontShader = nullptr; 421 const sh::ShaderVariable *backShader = nullptr; 422 ShaderType frontShaderStage = ShaderType::InvalidEnum; 423 ShaderType backShaderStage = ShaderType::InvalidEnum; 424 }; 425 426 using ProgramMergedVaryings = std::vector<ProgramVaryingRef>; 427 428 class Program final : angle::NonCopyable, public LabeledObject 429 { 430 public: 431 Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, ShaderProgramID handle); 432 void onDestroy(const Context *context); 433 434 ShaderProgramID id() const; 435 436 void setLabel(const Context *context, const std::string &label) override; 437 const std::string &getLabel() const override; 438 getImplementation()439 ANGLE_INLINE rx::ProgramImpl *getImplementation() const 440 { 441 ASSERT(!mLinkingState); 442 return mProgram; 443 } 444 445 void attachShader(const Context *context, Shader *shader); 446 void detachShader(const Context *context, Shader *shader); 447 int getAttachedShadersCount() const; 448 449 const Shader *getAttachedShader(ShaderType shaderType) const; 450 451 void bindAttributeLocation(GLuint index, const char *name); 452 void bindUniformLocation(UniformLocation location, const char *name); 453 454 // EXT_blend_func_extended 455 void bindFragmentOutputLocation(GLuint index, const char *name); 456 void bindFragmentOutputIndex(GLuint index, const char *name); 457 458 angle::Result linkMergedVaryings(const Context *context, 459 const ProgramExecutable &executable, 460 const ProgramMergedVaryings &mergedVaryings); 461 462 // KHR_parallel_shader_compile 463 // Try to link the program asynchrously. As a result, background threads may be launched to 464 // execute the linking tasks concurrently. 465 angle::Result link(const Context *context); 466 467 // Peek whether there is any running linking tasks. 468 bool isLinking() const; 469 isLinked()470 bool isLinked() const 471 { 472 ASSERT(!mLinkingState); 473 return mLinked; 474 } 475 476 angle::Result loadBinary(const Context *context, 477 GLenum binaryFormat, 478 const void *binary, 479 GLsizei length); 480 angle::Result saveBinary(Context *context, 481 GLenum *binaryFormat, 482 void *binary, 483 GLsizei bufSize, 484 GLsizei *length) const; 485 GLint getBinaryLength(Context *context) const; 486 void setBinaryRetrievableHint(bool retrievable); 487 bool getBinaryRetrievableHint() const; 488 489 void setSeparable(bool separable); 490 bool isSeparable() const; 491 492 void getAttachedShaders(GLsizei maxCount, GLsizei *count, ShaderProgramID *shaders) const; 493 494 GLuint getAttributeLocation(const std::string &name) const; 495 496 void getActiveAttribute(GLuint index, 497 GLsizei bufsize, 498 GLsizei *length, 499 GLint *size, 500 GLenum *type, 501 GLchar *name) const; 502 GLint getActiveAttributeCount() const; 503 GLint getActiveAttributeMaxLength() const; 504 const std::vector<sh::ShaderVariable> &getAttributes() const; 505 506 GLint getFragDataLocation(const std::string &name) const; 507 size_t getOutputResourceCount() const; 508 const std::vector<GLenum> &getOutputVariableTypes() const; getActiveOutputVariables()509 DrawBufferMask getActiveOutputVariables() const 510 { 511 ASSERT(!mLinkingState); 512 return mState.mActiveOutputVariables; 513 } 514 515 // EXT_blend_func_extended 516 GLint getFragDataIndex(const std::string &name) const; 517 518 void getActiveUniform(GLuint index, 519 GLsizei bufsize, 520 GLsizei *length, 521 GLint *size, 522 GLenum *type, 523 GLchar *name) const; 524 GLint getActiveUniformCount() const; 525 size_t getActiveBufferVariableCount() const; 526 GLint getActiveUniformMaxLength() const; 527 bool isValidUniformLocation(UniformLocation location) const; 528 const LinkedUniform &getUniformByLocation(UniformLocation location) const; 529 const VariableLocation &getUniformLocation(UniformLocation location) const; 530 getUniformLocations()531 const std::vector<VariableLocation> &getUniformLocations() const 532 { 533 ASSERT(!mLinkingState); 534 return mState.mUniformLocations; 535 } 536 getUniformByIndex(GLuint index)537 const LinkedUniform &getUniformByIndex(GLuint index) const 538 { 539 ASSERT(!mLinkingState); 540 return mState.mExecutable->getUniformByIndex(index); 541 } 542 543 const BufferVariable &getBufferVariableByIndex(GLuint index) const; 544 545 enum SetUniformResult 546 { 547 SamplerChanged, 548 NoSamplerChange, 549 }; 550 551 UniformLocation getUniformLocation(const std::string &name) const; 552 GLuint getUniformIndex(const std::string &name) const; 553 void setUniform1fv(UniformLocation location, GLsizei count, const GLfloat *v); 554 void setUniform2fv(UniformLocation location, GLsizei count, const GLfloat *v); 555 void setUniform3fv(UniformLocation location, GLsizei count, const GLfloat *v); 556 void setUniform4fv(UniformLocation location, GLsizei count, const GLfloat *v); 557 void setUniform1iv(Context *context, UniformLocation location, GLsizei count, const GLint *v); 558 void setUniform2iv(UniformLocation location, GLsizei count, const GLint *v); 559 void setUniform3iv(UniformLocation location, GLsizei count, const GLint *v); 560 void setUniform4iv(UniformLocation location, GLsizei count, const GLint *v); 561 void setUniform1uiv(UniformLocation location, GLsizei count, const GLuint *v); 562 void setUniform2uiv(UniformLocation location, GLsizei count, const GLuint *v); 563 void setUniform3uiv(UniformLocation location, GLsizei count, const GLuint *v); 564 void setUniform4uiv(UniformLocation location, GLsizei count, const GLuint *v); 565 void setUniformMatrix2fv(UniformLocation location, 566 GLsizei count, 567 GLboolean transpose, 568 const GLfloat *value); 569 void setUniformMatrix3fv(UniformLocation location, 570 GLsizei count, 571 GLboolean transpose, 572 const GLfloat *value); 573 void setUniformMatrix4fv(UniformLocation location, 574 GLsizei count, 575 GLboolean transpose, 576 const GLfloat *value); 577 void setUniformMatrix2x3fv(UniformLocation location, 578 GLsizei count, 579 GLboolean transpose, 580 const GLfloat *value); 581 void setUniformMatrix3x2fv(UniformLocation location, 582 GLsizei count, 583 GLboolean transpose, 584 const GLfloat *value); 585 void setUniformMatrix2x4fv(UniformLocation location, 586 GLsizei count, 587 GLboolean transpose, 588 const GLfloat *value); 589 void setUniformMatrix4x2fv(UniformLocation location, 590 GLsizei count, 591 GLboolean transpose, 592 const GLfloat *value); 593 void setUniformMatrix3x4fv(UniformLocation location, 594 GLsizei count, 595 GLboolean transpose, 596 const GLfloat *value); 597 void setUniformMatrix4x3fv(UniformLocation location, 598 GLsizei count, 599 GLboolean transpose, 600 const GLfloat *value); 601 602 void getUniformfv(const Context *context, UniformLocation location, GLfloat *params) const; 603 void getUniformiv(const Context *context, UniformLocation location, GLint *params) const; 604 void getUniformuiv(const Context *context, UniformLocation location, GLuint *params) const; 605 606 void getActiveUniformBlockName(const GLuint blockIndex, 607 GLsizei bufSize, 608 GLsizei *length, 609 GLchar *blockName) const; 610 void getActiveShaderStorageBlockName(const GLuint blockIndex, 611 GLsizei bufSize, 612 GLsizei *length, 613 GLchar *blockName) const; 614 getActiveUniformBlockCount()615 ANGLE_INLINE GLuint getActiveUniformBlockCount() const 616 { 617 ASSERT(!mLinkingState); 618 return static_cast<GLuint>(mState.mExecutable->getActiveUniformBlockCount()); 619 } 620 getActiveAtomicCounterBufferCount()621 ANGLE_INLINE GLuint getActiveAtomicCounterBufferCount() const 622 { 623 ASSERT(!mLinkingState); 624 return static_cast<GLuint>(mState.mExecutable->getActiveAtomicCounterBufferCount()); 625 } 626 getActiveShaderStorageBlockCount()627 ANGLE_INLINE GLuint getActiveShaderStorageBlockCount() const 628 { 629 ASSERT(!mLinkingState); 630 return static_cast<GLuint>(mState.mExecutable->getActiveShaderStorageBlockCount()); 631 } 632 633 GLint getActiveUniformBlockMaxNameLength() const; 634 GLint getActiveShaderStorageBlockMaxNameLength() const; 635 636 GLuint getUniformBlockIndex(const std::string &name) const; 637 GLuint getShaderStorageBlockIndex(const std::string &name) const; 638 639 void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding); 640 GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const; 641 GLuint getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const; 642 643 const InterfaceBlock &getUniformBlockByIndex(GLuint index) const; 644 const InterfaceBlock &getShaderStorageBlockByIndex(GLuint index) const; 645 646 void setTransformFeedbackVaryings(GLsizei count, 647 const GLchar *const *varyings, 648 GLenum bufferMode); 649 void getTransformFeedbackVarying(GLuint index, 650 GLsizei bufSize, 651 GLsizei *length, 652 GLsizei *size, 653 GLenum *type, 654 GLchar *name) const; 655 GLsizei getTransformFeedbackVaryingCount() const; 656 GLsizei getTransformFeedbackVaryingMaxLength() const; 657 GLenum getTransformFeedbackBufferMode() const; 658 GLuint getTransformFeedbackVaryingResourceIndex(const GLchar *name) const; 659 const TransformFeedbackVarying &getTransformFeedbackVaryingResource(GLuint index) const; 660 661 bool hasDrawIDUniform() const; 662 void setDrawIDUniform(GLint drawid); 663 664 bool hasBaseVertexUniform() const; 665 void setBaseVertexUniform(GLint baseVertex); 666 bool hasBaseInstanceUniform() const; 667 void setBaseInstanceUniform(GLuint baseInstance); 668 addRef()669 ANGLE_INLINE void addRef() 670 { 671 ASSERT(!mLinkingState); 672 mRefCount++; 673 } 674 release(const Context * context)675 ANGLE_INLINE void release(const Context *context) 676 { 677 ASSERT(!mLinkingState); 678 mRefCount--; 679 680 if (mRefCount == 0 && mDeleteStatus) 681 { 682 deleteSelf(context); 683 } 684 } 685 686 unsigned int getRefCount() const; isInUse()687 bool isInUse() const { return getRefCount() != 0; } 688 void flagForDeletion(); 689 bool isFlaggedForDeletion() const; 690 691 void validate(const Caps &caps); validateSamplers(InfoLog * infoLog,const Caps & caps)692 bool validateSamplers(InfoLog *infoLog, const Caps &caps) 693 { 694 // Skip cache if we're using an infolog, so we get the full error. 695 // Also skip the cache if the sample mapping has changed, or if we haven't ever validated. 696 if (infoLog == nullptr && mCachedValidateSamplersResult.valid()) 697 { 698 return mCachedValidateSamplersResult.value(); 699 } 700 701 return validateSamplersImpl(infoLog, caps); 702 } 703 704 bool isValidated() const; 705 getCachedValidateSamplersResult()706 Optional<bool> getCachedValidateSamplersResult() { return mCachedValidateSamplersResult; } setCachedValidateSamplersResult(bool result)707 void setCachedValidateSamplersResult(bool result) { mCachedValidateSamplersResult = result; } 708 709 const std::vector<SamplerBinding> &getSamplerBindings() const; getImageBindings()710 const std::vector<ImageBinding> &getImageBindings() const 711 { 712 ASSERT(!mLinkingState); 713 return mState.mImageBindings; 714 } 715 const sh::WorkGroupSize &getComputeShaderLocalSize() const; 716 PrimitiveMode getGeometryShaderInputPrimitiveType() const; 717 PrimitiveMode getGeometryShaderOutputPrimitiveType() const; 718 GLint getGeometryShaderInvocations() const; 719 GLint getGeometryShaderMaxVertices() const; 720 getState()721 const ProgramState &getState() const 722 { 723 ASSERT(!mLinkingState); 724 return mState; 725 } 726 727 static LinkMismatchError LinkValidateVariablesBase( 728 const sh::ShaderVariable &variable1, 729 const sh::ShaderVariable &variable2, 730 bool validatePrecision, 731 bool validateArraySize, 732 std::string *mismatchedStructOrBlockMemberName); 733 734 GLuint getInputResourceIndex(const GLchar *name) const; 735 GLuint getOutputResourceIndex(const GLchar *name) const; 736 void getInputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; 737 void getOutputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; 738 void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; 739 void getBufferVariableResourceName(GLuint index, 740 GLsizei bufSize, 741 GLsizei *length, 742 GLchar *name) const; 743 const sh::ShaderVariable &getInputResource(size_t index) const; 744 GLuint getResourceMaxNameSize(const sh::ShaderVariable &resource, GLint max) const; 745 GLuint getInputResourceMaxNameSize() const; 746 GLuint getOutputResourceMaxNameSize() const; 747 GLuint getResourceLocation(const GLchar *name, const sh::ShaderVariable &variable) const; 748 GLuint getInputResourceLocation(const GLchar *name) const; 749 GLuint getOutputResourceLocation(const GLchar *name) const; 750 const std::string getResourceName(const sh::ShaderVariable &resource) const; 751 const std::string getInputResourceName(GLuint index) const; 752 const std::string getOutputResourceName(GLuint index) const; 753 const sh::ShaderVariable &getOutputResource(size_t index) const; 754 755 const ProgramBindings &getAttributeBindings() const; 756 const ProgramAliasedBindings &getUniformLocationBindings() const; 757 const ProgramAliasedBindings &getFragmentOutputLocations() const; 758 const ProgramAliasedBindings &getFragmentOutputIndexes() const; 759 getNumViews()760 int getNumViews() const 761 { 762 ASSERT(!mLinkingState); 763 return mState.getNumViews(); 764 } 765 usesMultiview()766 bool usesMultiview() const { return mState.usesMultiview(); } 767 768 ComponentTypeMask getDrawBufferTypeMask() const; 769 770 const std::vector<GLsizei> &getTransformFeedbackStrides() const; 771 772 // Program dirty bits. 773 enum DirtyBitType 774 { 775 DIRTY_BIT_UNIFORM_BLOCK_BINDING_0, 776 DIRTY_BIT_UNIFORM_BLOCK_BINDING_MAX = 777 DIRTY_BIT_UNIFORM_BLOCK_BINDING_0 + IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS, 778 779 DIRTY_BIT_COUNT = DIRTY_BIT_UNIFORM_BLOCK_BINDING_MAX, 780 }; 781 782 using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>; 783 784 angle::Result syncState(const Context *context); 785 786 // Try to resolve linking. Inlined to make sure its overhead is as low as possible. resolveLink(const Context * context)787 void resolveLink(const Context *context) 788 { 789 if (mLinkingState) 790 { 791 resolveLinkImpl(context); 792 } 793 } 794 hasAnyDirtyBit()795 ANGLE_INLINE bool hasAnyDirtyBit() const { return mDirtyBits.any(); } 796 797 // Writes a program's binary to the output memory buffer. 798 angle::Result serialize(const Context *context, angle::MemoryBuffer *binaryOut) const; 799 serial()800 rx::Serial serial() const { return mSerial; } 801 getExecutable()802 const ProgramExecutable &getExecutable() const { return mState.getExecutable(); } getExecutable()803 ProgramExecutable &getExecutable() { return mState.getExecutable(); } 804 805 const char *validateDrawStates(const State &state, const gl::Extensions &extensions) const; 806 807 static void getFilteredVaryings(const std::vector<sh::ShaderVariable> &varyings, 808 std::vector<const sh::ShaderVariable *> *filteredVaryingsOut); 809 static bool doShaderVariablesMatch(int outputShaderVersion, 810 ShaderType outputShaderType, 811 ShaderType inputShaderType, 812 const sh::ShaderVariable &input, 813 const sh::ShaderVariable &output, 814 bool validateGeometryShaderInputs, 815 bool isSeparable, 816 gl::InfoLog &infoLog); 817 static bool linkValidateShaderInterfaceMatching( 818 const std::vector<sh::ShaderVariable> &outputVaryings, 819 const std::vector<sh::ShaderVariable> &inputVaryings, 820 ShaderType outputShaderType, 821 ShaderType inputShaderType, 822 int outputShaderVersion, 823 int inputShaderVersion, 824 bool isSeparable, 825 InfoLog &infoLog); 826 static bool linkValidateBuiltInVaryings(const std::vector<sh::ShaderVariable> &vertexVaryings, 827 const std::vector<sh::ShaderVariable> &fragmentVaryings, 828 int vertexShaderVersion, 829 InfoLog &infoLog); 830 831 private: 832 struct LinkingState; 833 834 ~Program() override; 835 836 // Loads program state according to the specified binary blob. 837 angle::Result deserialize(const Context *context, BinaryInputStream &stream, InfoLog &infoLog); 838 839 void unlink(); 840 void deleteSelf(const Context *context); 841 842 angle::Result linkImpl(const Context *context); 843 844 bool linkValidateShaders(InfoLog &infoLog); 845 bool linkAttributes(const Context *context, InfoLog &infoLog); 846 bool linkInterfaceBlocks(const Caps &caps, 847 const Version &version, 848 bool webglCompatibility, 849 InfoLog &infoLog, 850 GLuint *combinedShaderStorageBlocksCount); 851 bool linkVaryings(InfoLog &infoLog) const; 852 853 bool linkUniforms(const Caps &caps, 854 const Version &version, 855 InfoLog &infoLog, 856 const ProgramAliasedBindings &uniformLocationBindings, 857 GLuint *combinedImageUniformsCount, 858 std::vector<UnusedUniform> *unusedUniforms); 859 void linkSamplerAndImageBindings(GLuint *combinedImageUniformsCount); 860 bool linkAtomicCounterBuffers(); 861 862 void updateLinkedShaderStages(); 863 864 static LinkMismatchError LinkValidateVaryings(const sh::ShaderVariable &outputVarying, 865 const sh::ShaderVariable &inputVarying, 866 int shaderVersion, 867 bool validateGeometryShaderInputVarying, 868 bool isSeparable, 869 std::string *mismatchedStructFieldName); 870 871 bool linkValidateTransformFeedback(const Version &version, 872 InfoLog &infoLog, 873 const ProgramMergedVaryings &linkedVaryings, 874 ShaderType stage, 875 const Caps &caps) const; 876 877 void gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyings, ShaderType stage); 878 879 ProgramMergedVaryings getMergedVaryings() const; 880 int getOutputLocationForLink(const sh::ShaderVariable &outputVariable) const; 881 bool isOutputSecondaryForLink(const sh::ShaderVariable &outputVariable) const; 882 bool linkOutputVariables(const Caps &caps, 883 const Extensions &extensions, 884 const Version &version, 885 GLuint combinedImageUniformsCount, 886 GLuint combinedShaderStorageBlocksCount); 887 888 void setUniformValuesFromBindingQualifiers(); 889 bool shouldIgnoreUniform(UniformLocation location) const; 890 891 void initInterfaceBlockBindings(); 892 893 // Both these function update the cached uniform values and return a modified "count" 894 // so that the uniform update doesn't overflow the uniform. 895 template <typename T> 896 GLsizei clampUniformCount(const VariableLocation &locationInfo, 897 GLsizei count, 898 int vectorSize, 899 const T *v); 900 template <size_t cols, size_t rows, typename T> 901 GLsizei clampMatrixUniformCount(UniformLocation location, 902 GLsizei count, 903 GLboolean transpose, 904 const T *v); 905 906 void updateSamplerUniform(Context *context, 907 const VariableLocation &locationInfo, 908 GLsizei clampedCount, 909 const GLint *v); 910 911 template <typename DestT> 912 void getUniformInternal(const Context *context, 913 DestT *dataOut, 914 UniformLocation location, 915 GLenum nativeType, 916 int components) const; 917 918 void getResourceName(const std::string name, 919 GLsizei bufSize, 920 GLsizei *length, 921 GLchar *dest) const; 922 923 template <typename T> 924 GLint getActiveInterfaceBlockMaxNameLength(const std::vector<T> &resources) const; 925 926 GLuint getSamplerUniformBinding(const VariableLocation &uniformLocation) const; 927 GLuint getImageUniformBinding(const VariableLocation &uniformLocation) const; 928 929 bool validateSamplersImpl(InfoLog *infoLog, const Caps &caps); 930 931 // Block until linking is finished and resolve it. 932 void resolveLinkImpl(const gl::Context *context); 933 934 void postResolveLink(const gl::Context *context); 935 936 rx::Serial mSerial; 937 ProgramState mState; 938 rx::ProgramImpl *mProgram; 939 940 bool mValidated; 941 942 ProgramBindings mAttributeBindings; 943 944 // EXT_blend_func_extended 945 ProgramAliasedBindings mFragmentOutputLocations; 946 ProgramAliasedBindings mFragmentOutputIndexes; 947 948 bool mLinked; 949 std::unique_ptr<LinkingState> mLinkingState; 950 bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use 951 952 unsigned int mRefCount; 953 954 ShaderProgramManager *mResourceManager; 955 const ShaderProgramID mHandle; 956 957 // Cache for sampler validation 958 Optional<bool> mCachedValidateSamplersResult; 959 960 DirtyBits mDirtyBits; 961 }; 962 } // namespace gl 963 964 #endif // LIBANGLE_PROGRAM_H_ 965