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