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