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 = angle::HashMap<std::string, GLuint>::const_iterator; 176 const_iterator begin() const; 177 const_iterator end() const; 178 179 private: 180 angle::HashMap<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 262 { 263 return mExecutable->getSamplerBindings(); 264 } getImageBindings()265 const std::vector<ImageBinding> &getImageBindings() const 266 { 267 return getExecutable().getImageBindings(); 268 } getComputeShaderLocalSize()269 const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; } getDefaultUniformRange()270 const RangeUI &getDefaultUniformRange() const { return mExecutable->getDefaultUniformRange(); } getSamplerUniformRange()271 const RangeUI &getSamplerUniformRange() const { return mExecutable->getSamplerUniformRange(); } getImageUniformRange()272 const RangeUI &getImageUniformRange() const { return mExecutable->getImageUniformRange(); } getAtomicCounterUniformRange()273 const RangeUI &getAtomicCounterUniformRange() const { return mAtomicCounterUniformRange; } 274 getLinkedTransformFeedbackVaryings()275 const std::vector<TransformFeedbackVarying> &getLinkedTransformFeedbackVaryings() const 276 { 277 return mExecutable->getLinkedTransformFeedbackVaryings(); 278 } getTransformFeedbackStrides()279 const std::vector<GLsizei> &getTransformFeedbackStrides() const 280 { 281 return mExecutable->getTransformFeedbackStrides(); 282 } getAtomicCounterBuffers()283 const std::vector<AtomicCounterBuffer> &getAtomicCounterBuffers() const 284 { 285 return mExecutable->getAtomicCounterBuffers(); 286 } 287 288 GLuint getUniformIndexFromName(const std::string &name) const; 289 GLuint getUniformIndexFromLocation(UniformLocation location) const; 290 Optional<GLuint> getSamplerIndex(UniformLocation location) const; 291 bool isSamplerUniformIndex(GLuint index) const; 292 GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const; 293 GLuint getUniformIndexFromSamplerIndex(GLuint samplerIndex) const; 294 bool isImageUniformIndex(GLuint index) const; 295 GLuint getImageIndexFromUniformIndex(GLuint uniformIndex) const; 296 GLuint getAttributeLocation(const std::string &name) const; 297 298 GLuint getBufferVariableIndexFromName(const std::string &name) const; 299 getNumViews()300 int getNumViews() const { return mNumViews; } usesMultiview()301 bool usesMultiview() const { return mNumViews != -1; } 302 303 bool hasAttachedShader() const; 304 305 ShaderType getFirstAttachedShaderStageType() const; 306 ShaderType getLastAttachedShaderStageType() const; 307 getUniformLocationBindings()308 const ProgramAliasedBindings &getUniformLocationBindings() const 309 { 310 return mUniformLocationBindings; 311 } 312 getExecutable()313 const ProgramExecutable &getExecutable() const 314 { 315 ASSERT(mExecutable); 316 return *mExecutable; 317 } getExecutable()318 ProgramExecutable &getExecutable() 319 { 320 ASSERT(mExecutable); 321 return *mExecutable; 322 } 323 hasImages()324 bool hasImages() const { return !getImageBindings().empty(); } hasEarlyFragmentTestsOptimization()325 bool hasEarlyFragmentTestsOptimization() const { return mEarlyFramentTestsOptimization; } 326 isShaderMarkedForDetach(gl::ShaderType shaderType)327 bool isShaderMarkedForDetach(gl::ShaderType shaderType) const 328 { 329 return mAttachedShadersMarkedForDetach[shaderType]; 330 } 331 332 // A Program can only either be graphics or compute, but never both, so it 333 // can answer isCompute() based on which shaders it has. isCompute()334 bool isCompute() const { return mExecutable->hasLinkedShaderStage(ShaderType::Compute); } 335 getLabel()336 const std::string &getLabel() const { return mLabel; } getAttachedShadersMarkedForDetach()337 const ShaderMap<bool> &getAttachedShadersMarkedForDetach() const 338 { 339 return mAttachedShadersMarkedForDetach; 340 } 341 getLocationsUsedForXfbExtension()342 uint32_t getLocationsUsedForXfbExtension() const { return mLocationsUsedForXfbExtension; } 343 getOutputVariableTypes()344 const std::vector<GLenum> &getOutputVariableTypes() const { return mOutputVariableTypes; } 345 getDrawBufferTypeMask()346 ComponentTypeMask getDrawBufferTypeMask() const { return mDrawBufferTypeMask; } 347 hasBinaryRetrieveableHint()348 bool hasBinaryRetrieveableHint() const { return mBinaryRetrieveableHint; } 349 isSeparable()350 bool isSeparable() const { return mSeparable; } 351 getGeometryShaderInputPrimitiveType()352 PrimitiveMode getGeometryShaderInputPrimitiveType() const 353 { 354 return mGeometryShaderInputPrimitiveType; 355 } 356 getGeometryShaderOutputPrimitiveType()357 PrimitiveMode getGeometryShaderOutputPrimitiveType() const 358 { 359 return mGeometryShaderOutputPrimitiveType; 360 } 361 getGeometryShaderInvocations()362 int getGeometryShaderInvocations() const { return mGeometryShaderInvocations; } 363 getGeometryShaderMaxVertices()364 int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; } 365 getDrawIDLocation()366 int getDrawIDLocation() const { return mDrawIDLocation; } 367 getBaseVertexLocation()368 int getBaseVertexLocation() const { return mBaseVertexLocation; } 369 getBaseInstanceLocation()370 int getBaseInstanceLocation() const { return mBaseInstanceLocation; } 371 372 private: 373 friend class MemoryProgramCache; 374 friend class Program; 375 376 void updateTransformFeedbackStrides(); 377 void updateActiveSamplers(); 378 void updateProgramInterfaceInputs(); 379 void updateProgramInterfaceOutputs(); 380 381 // Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'. 382 void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex); 383 384 std::string mLabel; 385 386 sh::WorkGroupSize mComputeShaderLocalSize; 387 388 ShaderMap<Shader *> mAttachedShaders; 389 ShaderMap<bool> mAttachedShadersMarkedForDetach; 390 391 uint32_t mLocationsUsedForXfbExtension; 392 std::vector<std::string> mTransformFeedbackVaryingNames; 393 394 // For faster iteration on the blocks currently being bound. 395 UniformBlockBindingMask mActiveUniformBlockBindings; 396 397 std::vector<VariableLocation> mUniformLocations; 398 std::vector<BufferVariable> mBufferVariables; 399 RangeUI mAtomicCounterUniformRange; 400 401 // EXT_blend_func_extended secondary outputs (ones with index 1) in ESSL 3.00 shaders. 402 std::vector<VariableLocation> mSecondaryOutputLocations; 403 404 DrawBufferMask mActiveOutputVariables; 405 406 // Fragment output variable base types: FLOAT, INT, or UINT. Ordered by location. 407 std::vector<GLenum> mOutputVariableTypes; 408 ComponentTypeMask mDrawBufferTypeMask; 409 410 bool mBinaryRetrieveableHint; 411 bool mSeparable; 412 bool mEarlyFramentTestsOptimization; 413 414 // ANGLE_multiview. 415 int mNumViews; 416 417 // GL_EXT_geometry_shader. 418 PrimitiveMode mGeometryShaderInputPrimitiveType; 419 PrimitiveMode mGeometryShaderOutputPrimitiveType; 420 int mGeometryShaderInvocations; 421 int mGeometryShaderMaxVertices; 422 423 // GL_ANGLE_multi_draw 424 int mDrawIDLocation; 425 426 // GL_ANGLE_base_vertex_base_instance 427 int mBaseVertexLocation; 428 int mBaseInstanceLocation; 429 // Cached value of base vertex and base instance 430 // need to reset them to zero if using non base vertex or base instance draw calls. 431 GLint mCachedBaseVertex; 432 GLuint mCachedBaseInstance; 433 434 // Note that this has nothing to do with binding layout qualifiers that can be set for some 435 // uniforms in GLES3.1+. It is used to pre-set the location of uniforms. 436 ProgramAliasedBindings mUniformLocationBindings; 437 438 std::shared_ptr<ProgramExecutable> mExecutable; 439 }; 440 441 struct ProgramVaryingRef 442 { getProgramVaryingRef443 const sh::ShaderVariable *get(ShaderType stage) const 444 { 445 ASSERT(stage == frontShaderStage || stage == backShaderStage); 446 const sh::ShaderVariable *ref = stage == frontShaderStage ? frontShader : backShader; 447 ASSERT(ref); 448 return ref; 449 } 450 451 const sh::ShaderVariable *frontShader = nullptr; 452 const sh::ShaderVariable *backShader = nullptr; 453 ShaderType frontShaderStage = ShaderType::InvalidEnum; 454 ShaderType backShaderStage = ShaderType::InvalidEnum; 455 }; 456 457 using ProgramMergedVaryings = std::vector<ProgramVaryingRef>; 458 459 class Program final : public LabeledObject, public angle::Subject 460 { 461 public: 462 Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, ShaderProgramID handle); 463 void onDestroy(const Context *context); 464 465 ShaderProgramID id() const; 466 467 void setLabel(const Context *context, const std::string &label) override; 468 const std::string &getLabel() const override; 469 getImplementation()470 ANGLE_INLINE rx::ProgramImpl *getImplementation() const 471 { 472 ASSERT(!mLinkingState); 473 return mProgram; 474 } 475 476 void attachShader(const Context *context, Shader *shader); 477 void detachShader(const Context *context, Shader *shader); 478 int getAttachedShadersCount() const; 479 480 const Shader *getAttachedShader(ShaderType shaderType) const; 481 482 void bindAttributeLocation(GLuint index, const char *name); 483 void bindUniformLocation(UniformLocation location, const char *name); 484 485 // EXT_blend_func_extended 486 void bindFragmentOutputLocation(GLuint index, const char *name); 487 void bindFragmentOutputIndex(GLuint index, const char *name); 488 489 angle::Result linkMergedVaryings(const Context *context, 490 const ProgramExecutable &executable, 491 const ProgramMergedVaryings &mergedVaryings); 492 493 // KHR_parallel_shader_compile 494 // Try to link the program asynchrously. As a result, background threads may be launched to 495 // execute the linking tasks concurrently. 496 angle::Result link(const Context *context); 497 498 // Peek whether there is any running linking tasks. 499 bool isLinking() const; 500 isLinked()501 bool isLinked() const 502 { 503 ASSERT(!mLinkingState); 504 return mLinked; 505 } 506 507 angle::Result loadBinary(const Context *context, 508 GLenum binaryFormat, 509 const void *binary, 510 GLsizei length); 511 angle::Result saveBinary(Context *context, 512 GLenum *binaryFormat, 513 void *binary, 514 GLsizei bufSize, 515 GLsizei *length) const; 516 GLint getBinaryLength(Context *context) const; 517 void setBinaryRetrievableHint(bool retrievable); 518 bool getBinaryRetrievableHint() const; 519 520 void setSeparable(bool separable); 521 bool isSeparable() const; 522 523 void getAttachedShaders(GLsizei maxCount, GLsizei *count, ShaderProgramID *shaders) const; 524 525 GLuint getAttributeLocation(const std::string &name) const; 526 527 void getActiveAttribute(GLuint index, 528 GLsizei bufsize, 529 GLsizei *length, 530 GLint *size, 531 GLenum *type, 532 GLchar *name) const; 533 GLint getActiveAttributeCount() const; 534 GLint getActiveAttributeMaxLength() const; 535 const std::vector<sh::ShaderVariable> &getAttributes() const; 536 537 GLint getFragDataLocation(const std::string &name) const; 538 size_t getOutputResourceCount() const; 539 const std::vector<GLenum> &getOutputVariableTypes() const; getActiveOutputVariables()540 DrawBufferMask getActiveOutputVariables() const 541 { 542 ASSERT(!mLinkingState); 543 return mState.mActiveOutputVariables; 544 } 545 546 // EXT_blend_func_extended 547 GLint getFragDataIndex(const std::string &name) const; 548 549 void getActiveUniform(GLuint index, 550 GLsizei bufsize, 551 GLsizei *length, 552 GLint *size, 553 GLenum *type, 554 GLchar *name) const; 555 GLint getActiveUniformCount() const; 556 size_t getActiveBufferVariableCount() const; 557 GLint getActiveUniformMaxLength() const; 558 bool isValidUniformLocation(UniformLocation location) const; 559 const LinkedUniform &getUniformByLocation(UniformLocation location) const; 560 const VariableLocation &getUniformLocation(UniformLocation location) const; 561 getUniformLocations()562 const std::vector<VariableLocation> &getUniformLocations() const 563 { 564 ASSERT(!mLinkingState); 565 return mState.mUniformLocations; 566 } 567 getUniformByIndex(GLuint index)568 const LinkedUniform &getUniformByIndex(GLuint index) const 569 { 570 ASSERT(!mLinkingState); 571 return mState.mExecutable->getUniformByIndex(index); 572 } 573 574 const BufferVariable &getBufferVariableByIndex(GLuint index) const; 575 576 enum SetUniformResult 577 { 578 SamplerChanged, 579 NoSamplerChange, 580 }; 581 582 UniformLocation getUniformLocation(const std::string &name) const; 583 GLuint getUniformIndex(const std::string &name) const; 584 void setUniform1fv(UniformLocation location, GLsizei count, const GLfloat *v); 585 void setUniform2fv(UniformLocation location, GLsizei count, const GLfloat *v); 586 void setUniform3fv(UniformLocation location, GLsizei count, const GLfloat *v); 587 void setUniform4fv(UniformLocation location, GLsizei count, const GLfloat *v); 588 void setUniform1iv(Context *context, UniformLocation location, GLsizei count, const GLint *v); 589 void setUniform2iv(UniformLocation location, GLsizei count, const GLint *v); 590 void setUniform3iv(UniformLocation location, GLsizei count, const GLint *v); 591 void setUniform4iv(UniformLocation location, GLsizei count, const GLint *v); 592 void setUniform1uiv(UniformLocation location, GLsizei count, const GLuint *v); 593 void setUniform2uiv(UniformLocation location, GLsizei count, const GLuint *v); 594 void setUniform3uiv(UniformLocation location, GLsizei count, const GLuint *v); 595 void setUniform4uiv(UniformLocation location, GLsizei count, const GLuint *v); 596 void setUniformMatrix2fv(UniformLocation location, 597 GLsizei count, 598 GLboolean transpose, 599 const GLfloat *value); 600 void setUniformMatrix3fv(UniformLocation location, 601 GLsizei count, 602 GLboolean transpose, 603 const GLfloat *value); 604 void setUniformMatrix4fv(UniformLocation location, 605 GLsizei count, 606 GLboolean transpose, 607 const GLfloat *value); 608 void setUniformMatrix2x3fv(UniformLocation location, 609 GLsizei count, 610 GLboolean transpose, 611 const GLfloat *value); 612 void setUniformMatrix3x2fv(UniformLocation location, 613 GLsizei count, 614 GLboolean transpose, 615 const GLfloat *value); 616 void setUniformMatrix2x4fv(UniformLocation location, 617 GLsizei count, 618 GLboolean transpose, 619 const GLfloat *value); 620 void setUniformMatrix4x2fv(UniformLocation location, 621 GLsizei count, 622 GLboolean transpose, 623 const GLfloat *value); 624 void setUniformMatrix3x4fv(UniformLocation location, 625 GLsizei count, 626 GLboolean transpose, 627 const GLfloat *value); 628 void setUniformMatrix4x3fv(UniformLocation location, 629 GLsizei count, 630 GLboolean transpose, 631 const GLfloat *value); 632 633 void getUniformfv(const Context *context, UniformLocation location, GLfloat *params) const; 634 void getUniformiv(const Context *context, UniformLocation location, GLint *params) const; 635 void getUniformuiv(const Context *context, UniformLocation location, GLuint *params) const; 636 637 void getActiveUniformBlockName(const GLuint blockIndex, 638 GLsizei bufSize, 639 GLsizei *length, 640 GLchar *blockName) const; 641 void getActiveShaderStorageBlockName(const GLuint blockIndex, 642 GLsizei bufSize, 643 GLsizei *length, 644 GLchar *blockName) const; 645 getActiveUniformBlockCount()646 ANGLE_INLINE GLuint getActiveUniformBlockCount() const 647 { 648 ASSERT(!mLinkingState); 649 return static_cast<GLuint>(mState.mExecutable->getActiveUniformBlockCount()); 650 } 651 getActiveAtomicCounterBufferCount()652 ANGLE_INLINE GLuint getActiveAtomicCounterBufferCount() const 653 { 654 ASSERT(!mLinkingState); 655 return static_cast<GLuint>(mState.mExecutable->getActiveAtomicCounterBufferCount()); 656 } 657 getActiveShaderStorageBlockCount()658 ANGLE_INLINE GLuint getActiveShaderStorageBlockCount() const 659 { 660 ASSERT(!mLinkingState); 661 return static_cast<GLuint>(mState.mExecutable->getActiveShaderStorageBlockCount()); 662 } 663 664 GLint getActiveUniformBlockMaxNameLength() const; 665 GLint getActiveShaderStorageBlockMaxNameLength() const; 666 667 GLuint getUniformBlockIndex(const std::string &name) const; 668 GLuint getShaderStorageBlockIndex(const std::string &name) const; 669 670 void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding); 671 GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const; 672 GLuint getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const; 673 674 const InterfaceBlock &getUniformBlockByIndex(GLuint index) const; 675 const InterfaceBlock &getShaderStorageBlockByIndex(GLuint index) const; 676 677 void setTransformFeedbackVaryings(GLsizei count, 678 const GLchar *const *varyings, 679 GLenum bufferMode); 680 void getTransformFeedbackVarying(GLuint index, 681 GLsizei bufSize, 682 GLsizei *length, 683 GLsizei *size, 684 GLenum *type, 685 GLchar *name) const; 686 GLsizei getTransformFeedbackVaryingCount() const; 687 GLsizei getTransformFeedbackVaryingMaxLength() const; 688 GLenum getTransformFeedbackBufferMode() const; 689 GLuint getTransformFeedbackVaryingResourceIndex(const GLchar *name) const; 690 const TransformFeedbackVarying &getTransformFeedbackVaryingResource(GLuint index) const; 691 692 bool hasDrawIDUniform() const; 693 void setDrawIDUniform(GLint drawid); 694 695 bool hasBaseVertexUniform() const; 696 void setBaseVertexUniform(GLint baseVertex); 697 bool hasBaseInstanceUniform() const; 698 void setBaseInstanceUniform(GLuint baseInstance); 699 addRef()700 ANGLE_INLINE void addRef() 701 { 702 ASSERT(!mLinkingState); 703 mRefCount++; 704 } 705 release(const Context * context)706 ANGLE_INLINE void release(const Context *context) 707 { 708 ASSERT(!mLinkingState); 709 mRefCount--; 710 711 if (mRefCount == 0 && mDeleteStatus) 712 { 713 deleteSelf(context); 714 } 715 } 716 717 unsigned int getRefCount() const; isInUse()718 bool isInUse() const { return getRefCount() != 0; } 719 void flagForDeletion(); 720 bool isFlaggedForDeletion() const; 721 722 void validate(const Caps &caps); validateSamplers(InfoLog * infoLog,const Caps & caps)723 bool validateSamplers(InfoLog *infoLog, const Caps &caps) 724 { 725 // Skip cache if we're using an infolog, so we get the full error. 726 // Also skip the cache if the sample mapping has changed, or if we haven't ever validated. 727 if (infoLog == nullptr && mCachedValidateSamplersResult.valid()) 728 { 729 return mCachedValidateSamplersResult.value(); 730 } 731 732 return validateSamplersImpl(infoLog, caps); 733 } 734 735 bool isValidated() const; 736 getCachedValidateSamplersResult()737 Optional<bool> getCachedValidateSamplersResult() { return mCachedValidateSamplersResult; } setCachedValidateSamplersResult(bool result)738 void setCachedValidateSamplersResult(bool result) { mCachedValidateSamplersResult = result; } 739 getImageBindings()740 const std::vector<ImageBinding> &getImageBindings() const 741 { 742 ASSERT(!mLinkingState); 743 return getExecutable().getImageBindings(); 744 } 745 const sh::WorkGroupSize &getComputeShaderLocalSize() const; 746 PrimitiveMode getGeometryShaderInputPrimitiveType() const; 747 PrimitiveMode getGeometryShaderOutputPrimitiveType() const; 748 GLint getGeometryShaderInvocations() const; 749 GLint getGeometryShaderMaxVertices() const; 750 getState()751 const ProgramState &getState() const 752 { 753 ASSERT(!mLinkingState); 754 return mState; 755 } 756 757 static LinkMismatchError LinkValidateVariablesBase( 758 const sh::ShaderVariable &variable1, 759 const sh::ShaderVariable &variable2, 760 bool validatePrecision, 761 bool validateArraySize, 762 std::string *mismatchedStructOrBlockMemberName); 763 764 GLuint getInputResourceIndex(const GLchar *name) const; 765 GLuint getOutputResourceIndex(const GLchar *name) const; 766 void getInputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; 767 void getOutputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; 768 void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; 769 void getBufferVariableResourceName(GLuint index, 770 GLsizei bufSize, 771 GLsizei *length, 772 GLchar *name) const; 773 const sh::ShaderVariable &getInputResource(size_t index) const; 774 GLuint getResourceMaxNameSize(const sh::ShaderVariable &resource, GLint max) const; 775 GLuint getInputResourceMaxNameSize() const; 776 GLuint getOutputResourceMaxNameSize() const; 777 GLuint getResourceLocation(const GLchar *name, const sh::ShaderVariable &variable) const; 778 GLuint getInputResourceLocation(const GLchar *name) const; 779 GLuint getOutputResourceLocation(const GLchar *name) const; 780 const std::string getResourceName(const sh::ShaderVariable &resource) const; 781 const std::string getInputResourceName(GLuint index) const; 782 const std::string getOutputResourceName(GLuint index) const; 783 const sh::ShaderVariable &getOutputResource(size_t index) const; 784 785 const ProgramBindings &getAttributeBindings() const; 786 const ProgramAliasedBindings &getUniformLocationBindings() const; 787 const ProgramAliasedBindings &getFragmentOutputLocations() const; 788 const ProgramAliasedBindings &getFragmentOutputIndexes() const; 789 getNumViews()790 int getNumViews() const 791 { 792 ASSERT(!mLinkingState); 793 return mState.getNumViews(); 794 } 795 usesMultiview()796 bool usesMultiview() const { return mState.usesMultiview(); } 797 798 ComponentTypeMask getDrawBufferTypeMask() const; 799 800 const std::vector<GLsizei> &getTransformFeedbackStrides() const; 801 802 // Program dirty bits. 803 enum DirtyBitType 804 { 805 DIRTY_BIT_UNIFORM_BLOCK_BINDING_0, 806 DIRTY_BIT_UNIFORM_BLOCK_BINDING_MAX = 807 DIRTY_BIT_UNIFORM_BLOCK_BINDING_0 + IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS, 808 809 DIRTY_BIT_COUNT = DIRTY_BIT_UNIFORM_BLOCK_BINDING_MAX, 810 }; 811 812 using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>; 813 814 angle::Result syncState(const Context *context); 815 816 // Try to resolve linking. Inlined to make sure its overhead is as low as possible. resolveLink(const Context * context)817 void resolveLink(const Context *context) 818 { 819 if (mLinkingState) 820 { 821 resolveLinkImpl(context); 822 } 823 } 824 hasAnyDirtyBit()825 ANGLE_INLINE bool hasAnyDirtyBit() const { return mDirtyBits.any(); } 826 827 // Writes a program's binary to the output memory buffer. 828 angle::Result serialize(const Context *context, angle::MemoryBuffer *binaryOut) const; 829 serial()830 rx::Serial serial() const { return mSerial; } 831 getExecutable()832 const ProgramExecutable &getExecutable() const { return mState.getExecutable(); } getExecutable()833 ProgramExecutable &getExecutable() { return mState.getExecutable(); } 834 835 const char *validateDrawStates(const State &state, const gl::Extensions &extensions) const; 836 837 static void getFilteredVaryings(const std::vector<sh::ShaderVariable> &varyings, 838 std::vector<const sh::ShaderVariable *> *filteredVaryingsOut); 839 static bool doShaderVariablesMatch(int outputShaderVersion, 840 ShaderType outputShaderType, 841 ShaderType inputShaderType, 842 const sh::ShaderVariable &input, 843 const sh::ShaderVariable &output, 844 bool validateGeometryShaderInputs, 845 bool isSeparable, 846 gl::InfoLog &infoLog); 847 static bool linkValidateShaderInterfaceMatching( 848 const std::vector<sh::ShaderVariable> &outputVaryings, 849 const std::vector<sh::ShaderVariable> &inputVaryings, 850 ShaderType outputShaderType, 851 ShaderType inputShaderType, 852 int outputShaderVersion, 853 int inputShaderVersion, 854 bool isSeparable, 855 InfoLog &infoLog); 856 static bool linkValidateBuiltInVaryings(const std::vector<sh::ShaderVariable> &vertexVaryings, 857 const std::vector<sh::ShaderVariable> &fragmentVaryings, 858 int vertexShaderVersion, 859 InfoLog &infoLog); 860 861 void fillProgramStateMap(ShaderMap<const ProgramState *> *programStatesOut); 862 863 private: 864 struct LinkingState; 865 866 ~Program() override; 867 868 // Loads program state according to the specified binary blob. 869 angle::Result deserialize(const Context *context, BinaryInputStream &stream, InfoLog &infoLog); 870 871 void unlink(); 872 void deleteSelf(const Context *context); 873 874 angle::Result linkImpl(const Context *context); 875 876 bool linkValidateShaders(InfoLog &infoLog); 877 bool linkAttributes(const Context *context, InfoLog &infoLog); 878 bool linkInterfaceBlocks(const Caps &caps, 879 const Version &version, 880 bool webglCompatibility, 881 InfoLog &infoLog, 882 GLuint *combinedShaderStorageBlocksCount); 883 bool linkVaryings(InfoLog &infoLog) const; 884 885 bool linkUniforms(const Caps &caps, 886 const Version &version, 887 InfoLog &infoLog, 888 const ProgramAliasedBindings &uniformLocationBindings, 889 GLuint *combinedImageUniformsCount, 890 std::vector<UnusedUniform> *unusedUniforms); 891 void linkSamplerAndImageBindings(GLuint *combinedImageUniformsCount); 892 bool linkAtomicCounterBuffers(); 893 894 void updateLinkedShaderStages(); 895 896 static LinkMismatchError LinkValidateVaryings(const sh::ShaderVariable &outputVarying, 897 const sh::ShaderVariable &inputVarying, 898 int shaderVersion, 899 bool validateGeometryShaderInputVarying, 900 bool isSeparable, 901 std::string *mismatchedStructFieldName); 902 903 bool linkValidateTransformFeedback(const Version &version, 904 InfoLog &infoLog, 905 const ProgramMergedVaryings &linkedVaryings, 906 ShaderType stage, 907 const Caps &caps) const; 908 909 void gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyings, ShaderType stage); 910 911 ProgramMergedVaryings getMergedVaryings() const; 912 int getOutputLocationForLink(const sh::ShaderVariable &outputVariable) const; 913 bool isOutputSecondaryForLink(const sh::ShaderVariable &outputVariable) const; 914 bool linkOutputVariables(const Caps &caps, 915 const Extensions &extensions, 916 const Version &version, 917 GLuint combinedImageUniformsCount, 918 GLuint combinedShaderStorageBlocksCount); 919 920 void setUniformValuesFromBindingQualifiers(); 921 bool shouldIgnoreUniform(UniformLocation location) const; 922 923 void initInterfaceBlockBindings(); 924 925 // Both these function update the cached uniform values and return a modified "count" 926 // so that the uniform update doesn't overflow the uniform. 927 template <typename T> 928 GLsizei clampUniformCount(const VariableLocation &locationInfo, 929 GLsizei count, 930 int vectorSize, 931 const T *v); 932 template <size_t cols, size_t rows, typename T> 933 GLsizei clampMatrixUniformCount(UniformLocation location, 934 GLsizei count, 935 GLboolean transpose, 936 const T *v); 937 938 void updateSamplerUniform(Context *context, 939 const VariableLocation &locationInfo, 940 GLsizei clampedCount, 941 const GLint *v); 942 943 template <typename DestT> 944 void getUniformInternal(const Context *context, 945 DestT *dataOut, 946 UniformLocation location, 947 GLenum nativeType, 948 int components) const; 949 950 void getResourceName(const std::string name, 951 GLsizei bufSize, 952 GLsizei *length, 953 GLchar *dest) const; 954 955 template <typename T> 956 GLint getActiveInterfaceBlockMaxNameLength(const std::vector<T> &resources) const; 957 958 GLuint getSamplerUniformBinding(const VariableLocation &uniformLocation) const; 959 GLuint getImageUniformBinding(const VariableLocation &uniformLocation) const; 960 961 bool validateSamplersImpl(InfoLog *infoLog, const Caps &caps); 962 963 // Block until linking is finished and resolve it. 964 void resolveLinkImpl(const gl::Context *context); 965 966 void postResolveLink(const gl::Context *context); 967 968 rx::Serial mSerial; 969 ProgramState mState; 970 rx::ProgramImpl *mProgram; 971 972 bool mValidated; 973 974 ProgramBindings mAttributeBindings; 975 976 // EXT_blend_func_extended 977 ProgramAliasedBindings mFragmentOutputLocations; 978 ProgramAliasedBindings mFragmentOutputIndexes; 979 980 bool mLinked; 981 std::unique_ptr<LinkingState> mLinkingState; 982 bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use 983 984 unsigned int mRefCount; 985 986 ShaderProgramManager *mResourceManager; 987 const ShaderProgramID mHandle; 988 989 // Cache for sampler validation 990 Optional<bool> mCachedValidateSamplersResult; 991 992 DirtyBits mDirtyBits; 993 }; 994 } // namespace gl 995 996 #endif // LIBANGLE_PROGRAM_H_ 997