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 // Texture.h: Defines the gl::Texture class [OpenGL ES 2.0.24] section 3.7 page 63. 8 9 #ifndef LIBANGLE_TEXTURE_H_ 10 #define LIBANGLE_TEXTURE_H_ 11 12 #include <map> 13 #include <vector> 14 15 #include "angle_gl.h" 16 #include "common/Optional.h" 17 #include "common/debug.h" 18 #include "common/utilities.h" 19 #include "libANGLE/Caps.h" 20 #include "libANGLE/Constants.h" 21 #include "libANGLE/Debug.h" 22 #include "libANGLE/Error.h" 23 #include "libANGLE/FramebufferAttachment.h" 24 #include "libANGLE/Image.h" 25 #include "libANGLE/Observer.h" 26 #include "libANGLE/Stream.h" 27 #include "libANGLE/angletypes.h" 28 #include "libANGLE/formatutils.h" 29 30 namespace egl 31 { 32 class Surface; 33 class Stream; 34 } // namespace egl 35 36 namespace rx 37 { 38 class GLImplFactory; 39 class TextureImpl; 40 class TextureGL; 41 } // namespace rx 42 43 namespace gl 44 { 45 class Framebuffer; 46 class MemoryObject; 47 class Sampler; 48 class State; 49 class Texture; 50 51 constexpr GLuint kInitialMaxLevel = 1000; 52 53 bool IsMipmapFiltered(GLenum minFilterMode); 54 55 // Convert a given filter mode to nearest filtering. 56 GLenum ConvertToNearestFilterMode(GLenum filterMode); 57 58 // Convert a given filter mode to nearest mip filtering. 59 GLenum ConvertToNearestMipFilterMode(GLenum filterMode); 60 61 struct ImageDesc final 62 { 63 ImageDesc(); 64 ImageDesc(const Extents &size, const Format &format, const InitState initState); 65 ImageDesc(const Extents &size, 66 const Format &format, 67 const GLsizei samples, 68 const bool fixedSampleLocations, 69 const InitState initState); 70 71 ImageDesc(const ImageDesc &other) = default; 72 ImageDesc &operator=(const ImageDesc &other) = default; 73 74 GLint getMemorySize() const; 75 76 Extents size; 77 Format format; 78 GLsizei samples; 79 bool fixedSampleLocations; 80 81 // Needed for robust resource initialization. 82 InitState initState; 83 }; 84 85 struct SwizzleState final 86 { 87 SwizzleState(); 88 SwizzleState(GLenum red, GLenum green, GLenum blue, GLenum alpha); 89 SwizzleState(const SwizzleState &other) = default; 90 SwizzleState &operator=(const SwizzleState &other) = default; 91 92 bool swizzleRequired() const; 93 94 bool operator==(const SwizzleState &other) const; 95 bool operator!=(const SwizzleState &other) const; 96 97 GLenum swizzleRed; 98 GLenum swizzleGreen; 99 GLenum swizzleBlue; 100 GLenum swizzleAlpha; 101 }; 102 103 // State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec. 104 class TextureState final : private angle::NonCopyable 105 { 106 public: 107 TextureState(TextureType type); 108 ~TextureState(); 109 110 bool swizzleRequired() const; 111 GLuint getEffectiveBaseLevel() const; 112 GLuint getEffectiveMaxLevel() const; 113 114 // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10. 115 GLuint getMipmapMaxLevel() const; 116 117 // Returns true if base level changed. 118 bool setBaseLevel(GLuint baseLevel); getBaseLevel()119 GLuint getBaseLevel() const { return mBaseLevel; } 120 bool setMaxLevel(GLuint maxLevel); getMaxLevel()121 GLuint getMaxLevel() const { return mMaxLevel; } 122 123 bool isCubeComplete() const; 124 compatibleWithSamplerFormatForWebGL(SamplerFormat format,const SamplerState & samplerState)125 ANGLE_INLINE bool compatibleWithSamplerFormatForWebGL(SamplerFormat format, 126 const SamplerState &samplerState) const 127 { 128 if (!mCachedSamplerFormatValid || 129 mCachedSamplerCompareMode != samplerState.getCompareMode()) 130 { 131 mCachedSamplerFormat = computeRequiredSamplerFormat(samplerState); 132 mCachedSamplerCompareMode = samplerState.getCompareMode(); 133 mCachedSamplerFormatValid = true; 134 } 135 // Incomplete textures are compatible with any sampler format. 136 return mCachedSamplerFormat == SamplerFormat::InvalidEnum || format == mCachedSamplerFormat; 137 } 138 139 const ImageDesc &getImageDesc(TextureTarget target, size_t level) const; 140 const ImageDesc &getImageDesc(const ImageIndex &imageIndex) const; 141 getType()142 TextureType getType() const { return mType; } getSwizzleState()143 const SwizzleState &getSwizzleState() const { return mSwizzleState; } getSamplerState()144 const SamplerState &getSamplerState() const { return mSamplerState; } getUsage()145 GLenum getUsage() const { return mUsage; } hasProtectedContent()146 bool hasProtectedContent() const { return mHasProtectedContent; } getDepthStencilTextureMode()147 GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; } isStencilMode()148 bool isStencilMode() const { return mDepthStencilTextureMode == GL_STENCIL_INDEX; } 149 hasBeenBoundAsImage()150 bool hasBeenBoundAsImage() const { return mHasBeenBoundAsImage; } hasBeenBoundAsAttachment()151 bool hasBeenBoundAsAttachment() const { return mHasBeenBoundAsAttachment; } 152 getSRGBOverride()153 gl::SrgbOverride getSRGBOverride() const { return mSrgbOverride; } 154 155 // Returns the desc of the base level. Only valid for cube-complete/mip-complete textures. 156 const ImageDesc &getBaseLevelDesc() const; 157 const ImageDesc &getLevelZeroDesc() const; 158 159 // GLES1 emulation: For GL_OES_draw_texture 160 void setCrop(const Rectangle &rect); 161 const Rectangle &getCrop() const; 162 163 // GLES1 emulation: Auto-mipmap generation is a texparameter 164 void setGenerateMipmapHint(GLenum hint); 165 GLenum getGenerateMipmapHint() const; 166 167 // Return the enabled mipmap level count. 168 GLuint getEnabledLevelCount() const; 169 getImmutableFormat()170 bool getImmutableFormat() const { return mImmutableFormat; } getImmutableLevels()171 GLuint getImmutableLevels() const { return mImmutableLevels; } 172 getImageDescs()173 const std::vector<ImageDesc> &getImageDescs() const { return mImageDescs; } 174 getInitState()175 InitState getInitState() const { return mInitState; } 176 getBuffer()177 const OffsetBindingPointer<Buffer> &getBuffer() const { return mBuffer; } 178 getLabel()179 const std::string &getLabel() const { return mLabel; } 180 181 private: 182 // Texture needs access to the ImageDesc functions. 183 friend class Texture; 184 friend bool operator==(const TextureState &a, const TextureState &b); 185 186 bool computeSamplerCompleteness(const SamplerState &samplerState, const State &state) const; 187 bool computeMipmapCompleteness() const; 188 bool computeLevelCompleteness(TextureTarget target, size_t level) const; 189 SamplerFormat computeRequiredSamplerFormat(const SamplerState &samplerState) const; 190 191 TextureTarget getBaseImageTarget() const; 192 193 void setImageDesc(TextureTarget target, size_t level, const ImageDesc &desc); 194 void setImageDescChain(GLuint baselevel, 195 GLuint maxLevel, 196 Extents baseSize, 197 const Format &format, 198 InitState initState); 199 void setImageDescChainMultisample(Extents baseSize, 200 const Format &format, 201 GLsizei samples, 202 bool fixedSampleLocations, 203 InitState initState); 204 205 void clearImageDesc(TextureTarget target, size_t level); 206 void clearImageDescs(); 207 208 const TextureType mType; 209 210 SwizzleState mSwizzleState; 211 212 SamplerState mSamplerState; 213 214 SrgbOverride mSrgbOverride; 215 216 GLuint mBaseLevel; 217 GLuint mMaxLevel; 218 219 GLenum mDepthStencilTextureMode; 220 221 bool mHasBeenBoundAsImage; 222 bool mHasBeenBoundAsAttachment; 223 224 bool mImmutableFormat; 225 GLuint mImmutableLevels; 226 227 // From GL_ANGLE_texture_usage 228 GLenum mUsage; 229 230 // GL_EXT_protected_textures 231 bool mHasProtectedContent; 232 233 std::vector<ImageDesc> mImageDescs; 234 235 // GLES1 emulation: Texture crop rectangle 236 // For GL_OES_draw_texture 237 Rectangle mCropRect; 238 239 // GLES1 emulation: Generate-mipmap hint per texture 240 GLenum mGenerateMipmapHint; 241 242 // GL_OES_texture_buffer / GLES3.2 243 OffsetBindingPointer<Buffer> mBuffer; 244 245 InitState mInitState; 246 247 mutable SamplerFormat mCachedSamplerFormat; 248 mutable GLenum mCachedSamplerCompareMode; 249 mutable bool mCachedSamplerFormatValid; 250 std::string mLabel; 251 }; 252 253 bool operator==(const TextureState &a, const TextureState &b); 254 bool operator!=(const TextureState &a, const TextureState &b); 255 256 class Texture final : public RefCountObject<TextureID>, 257 public egl::ImageSibling, 258 public LabeledObject 259 { 260 public: 261 Texture(rx::GLImplFactory *factory, TextureID id, TextureType type); 262 ~Texture() override; 263 264 void onDestroy(const Context *context) override; 265 266 void setLabel(const Context *context, const std::string &label) override; 267 const std::string &getLabel() const override; 268 getType()269 TextureType getType() const { return mState.mType; } 270 271 void setSwizzleRed(const Context *context, GLenum swizzleRed); 272 GLenum getSwizzleRed() const; 273 274 void setSwizzleGreen(const Context *context, GLenum swizzleGreen); 275 GLenum getSwizzleGreen() const; 276 277 void setSwizzleBlue(const Context *context, GLenum swizzleBlue); 278 GLenum getSwizzleBlue() const; 279 280 void setSwizzleAlpha(const Context *context, GLenum swizzleAlpha); 281 GLenum getSwizzleAlpha() const; 282 283 void setMinFilter(const Context *context, GLenum minFilter); 284 GLenum getMinFilter() const; 285 286 void setMagFilter(const Context *context, GLenum magFilter); 287 GLenum getMagFilter() const; 288 289 void setWrapS(const Context *context, GLenum wrapS); 290 GLenum getWrapS() const; 291 292 void setWrapT(const Context *context, GLenum wrapT); 293 GLenum getWrapT() const; 294 295 void setWrapR(const Context *context, GLenum wrapR); 296 GLenum getWrapR() const; 297 298 void setMaxAnisotropy(const Context *context, float maxAnisotropy); 299 float getMaxAnisotropy() const; 300 301 void setMinLod(const Context *context, GLfloat minLod); 302 GLfloat getMinLod() const; 303 304 void setMaxLod(const Context *context, GLfloat maxLod); 305 GLfloat getMaxLod() const; 306 307 void setCompareMode(const Context *context, GLenum compareMode); 308 GLenum getCompareMode() const; 309 310 void setCompareFunc(const Context *context, GLenum compareFunc); 311 GLenum getCompareFunc() const; 312 313 void setSRGBDecode(const Context *context, GLenum sRGBDecode); 314 GLenum getSRGBDecode() const; 315 316 void setSRGBOverride(const Context *context, GLenum sRGBOverride); 317 GLenum getSRGBOverride() const; 318 319 const SamplerState &getSamplerState() const; 320 321 angle::Result setBaseLevel(const Context *context, GLuint baseLevel); 322 GLuint getBaseLevel() const; 323 324 void setMaxLevel(const Context *context, GLuint maxLevel); 325 GLuint getMaxLevel() const; 326 327 void setDepthStencilTextureMode(const Context *context, GLenum mode); 328 GLenum getDepthStencilTextureMode() const; 329 330 bool getImmutableFormat() const; 331 332 GLuint getImmutableLevels() const; 333 334 void setUsage(const Context *context, GLenum usage); 335 GLenum getUsage() const; 336 337 void setProtectedContent(Context *context, bool hasProtectedContent); 338 bool hasProtectedContent() const override; 339 getState()340 const TextureState &getState() const { return mState; } 341 342 void setBorderColor(const Context *context, const ColorGeneric &color); 343 const ColorGeneric &getBorderColor() const; 344 345 angle::Result setBuffer(const Context *context, gl::Buffer *buffer, GLenum internalFormat); 346 angle::Result setBufferRange(const Context *context, 347 gl::Buffer *buffer, 348 GLenum internalFormat, 349 GLintptr offset, 350 GLsizeiptr size); 351 const OffsetBindingPointer<Buffer> &getBuffer() const; 352 353 GLint getRequiredTextureImageUnits(const Context *context) const; 354 355 const TextureState &getTextureState() const; 356 357 const Extents &getExtents(TextureTarget target, size_t level) const; 358 size_t getWidth(TextureTarget target, size_t level) const; 359 size_t getHeight(TextureTarget target, size_t level) const; 360 size_t getDepth(TextureTarget target, size_t level) const; 361 GLsizei getSamples(TextureTarget target, size_t level) const; 362 bool getFixedSampleLocations(TextureTarget target, size_t level) const; 363 const Format &getFormat(TextureTarget target, size_t level) const; 364 365 // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10. 366 GLuint getMipmapMaxLevel() const; 367 368 bool isMipmapComplete() const; 369 370 angle::Result setImage(Context *context, 371 const PixelUnpackState &unpackState, 372 Buffer *unpackBuffer, 373 TextureTarget target, 374 GLint level, 375 GLenum internalFormat, 376 const Extents &size, 377 GLenum format, 378 GLenum type, 379 const uint8_t *pixels); 380 angle::Result setSubImage(Context *context, 381 const PixelUnpackState &unpackState, 382 Buffer *unpackBuffer, 383 TextureTarget target, 384 GLint level, 385 const Box &area, 386 GLenum format, 387 GLenum type, 388 const uint8_t *pixels); 389 390 angle::Result setCompressedImage(Context *context, 391 const PixelUnpackState &unpackState, 392 TextureTarget target, 393 GLint level, 394 GLenum internalFormat, 395 const Extents &size, 396 size_t imageSize, 397 const uint8_t *pixels); 398 angle::Result setCompressedSubImage(const Context *context, 399 const PixelUnpackState &unpackState, 400 TextureTarget target, 401 GLint level, 402 const Box &area, 403 GLenum format, 404 size_t imageSize, 405 const uint8_t *pixels); 406 407 angle::Result copyImage(Context *context, 408 TextureTarget target, 409 GLint level, 410 const Rectangle &sourceArea, 411 GLenum internalFormat, 412 Framebuffer *source); 413 angle::Result copySubImage(Context *context, 414 const ImageIndex &index, 415 const Offset &destOffset, 416 const Rectangle &sourceArea, 417 Framebuffer *source); 418 419 angle::Result copyRenderbufferSubData(Context *context, 420 const gl::Renderbuffer *srcBuffer, 421 GLint srcLevel, 422 GLint srcX, 423 GLint srcY, 424 GLint srcZ, 425 GLint dstLevel, 426 GLint dstX, 427 GLint dstY, 428 GLint dstZ, 429 GLsizei srcWidth, 430 GLsizei srcHeight, 431 GLsizei srcDepth); 432 433 angle::Result copyTextureSubData(Context *context, 434 const gl::Texture *srcTexture, 435 GLint srcLevel, 436 GLint srcX, 437 GLint srcY, 438 GLint srcZ, 439 GLint dstLevel, 440 GLint dstX, 441 GLint dstY, 442 GLint dstZ, 443 GLsizei srcWidth, 444 GLsizei srcHeight, 445 GLsizei srcDepth); 446 447 angle::Result copyTexture(Context *context, 448 TextureTarget target, 449 GLint level, 450 GLenum internalFormat, 451 GLenum type, 452 GLint sourceLevel, 453 bool unpackFlipY, 454 bool unpackPremultiplyAlpha, 455 bool unpackUnmultiplyAlpha, 456 Texture *source); 457 angle::Result copySubTexture(const Context *context, 458 TextureTarget target, 459 GLint level, 460 const Offset &destOffset, 461 GLint sourceLevel, 462 const Box &sourceBox, 463 bool unpackFlipY, 464 bool unpackPremultiplyAlpha, 465 bool unpackUnmultiplyAlpha, 466 Texture *source); 467 angle::Result copyCompressedTexture(Context *context, const Texture *source); 468 469 angle::Result setStorage(Context *context, 470 TextureType type, 471 GLsizei levels, 472 GLenum internalFormat, 473 const Extents &size); 474 475 angle::Result setStorageMultisample(Context *context, 476 TextureType type, 477 GLsizei samplesIn, 478 GLint internalformat, 479 const Extents &size, 480 bool fixedSampleLocations); 481 482 angle::Result setStorageExternalMemory(Context *context, 483 TextureType type, 484 GLsizei levels, 485 GLenum internalFormat, 486 const Extents &size, 487 MemoryObject *memoryObject, 488 GLuint64 offset, 489 GLbitfield createFlags, 490 GLbitfield usageFlags, 491 const void *imageCreateInfoPNext); 492 493 angle::Result setImageExternal(Context *context, 494 TextureTarget target, 495 GLint level, 496 GLenum internalFormat, 497 const Extents &size, 498 GLenum format, 499 GLenum type); 500 501 angle::Result setEGLImageTarget(Context *context, TextureType type, egl::Image *imageTarget); 502 503 angle::Result generateMipmap(Context *context); 504 505 void onBindAsImageTexture(); 506 507 egl::Surface *getBoundSurface() const; 508 egl::Stream *getBoundStream() const; 509 510 GLint getMemorySize() const; 511 GLint getLevelMemorySize(TextureTarget target, GLint level) const; 512 513 void signalDirtyStorage(InitState initState); 514 515 bool isSamplerComplete(const Context *context, const Sampler *optionalSampler); 516 517 GLenum getImplementationColorReadFormat(const Context *context) const; 518 GLenum getImplementationColorReadType(const Context *context) const; 519 520 // We pass the pack buffer and state explicitly so they can be overridden during capture. 521 angle::Result getTexImage(const Context *context, 522 const PixelPackState &packState, 523 Buffer *packBuffer, 524 TextureTarget target, 525 GLint level, 526 GLenum format, 527 GLenum type, 528 void *pixels); 529 530 angle::Result getCompressedTexImage(const Context *context, 531 const PixelPackState &packState, 532 Buffer *packBuffer, 533 TextureTarget target, 534 GLint level, 535 void *pixels); 536 getImplementation()537 rx::TextureImpl *getImplementation() const { return mTexture; } 538 539 // FramebufferAttachmentObject implementation 540 Extents getAttachmentSize(const ImageIndex &imageIndex) const override; 541 Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override; 542 GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override; 543 bool isRenderable(const Context *context, 544 GLenum binding, 545 const ImageIndex &imageIndex) const override; 546 547 bool getAttachmentFixedSampleLocations(const ImageIndex &imageIndex) const; 548 549 // GLES1 emulation 550 void setCrop(const Rectangle &rect); 551 const Rectangle &getCrop() const; 552 void setGenerateMipmapHint(GLenum generate); 553 GLenum getGenerateMipmapHint() const; 554 555 void onAttach(const Context *context, rx::Serial framebufferSerial) override; 556 void onDetach(const Context *context, rx::Serial framebufferSerial) override; 557 558 // Used specifically for FramebufferAttachmentObject. 559 GLuint getId() const override; 560 561 GLuint getNativeID() const; 562 563 // Needed for robust resource init. 564 angle::Result ensureInitialized(const Context *context); 565 InitState initState(const ImageIndex &imageIndex) const override; initState()566 InitState initState() const { return mState.mInitState; } 567 void setInitState(const ImageIndex &imageIndex, InitState initState) override; 568 void setInitState(InitState initState); 569 isBoundToFramebuffer(rx::Serial framebufferSerial)570 bool isBoundToFramebuffer(rx::Serial framebufferSerial) const 571 { 572 for (size_t index = 0; index < mBoundFramebufferSerials.size(); ++index) 573 { 574 if (mBoundFramebufferSerials[index] == framebufferSerial) 575 return true; 576 } 577 578 return false; 579 } 580 isDepthOrStencil()581 bool isDepthOrStencil() const 582 { 583 return mState.getBaseLevelDesc().format.info->isDepthOrStencil(); 584 } 585 586 enum DirtyBitType 587 { 588 // Sampler state 589 DIRTY_BIT_MIN_FILTER, 590 DIRTY_BIT_MAG_FILTER, 591 DIRTY_BIT_WRAP_S, 592 DIRTY_BIT_WRAP_T, 593 DIRTY_BIT_WRAP_R, 594 DIRTY_BIT_MAX_ANISOTROPY, 595 DIRTY_BIT_MIN_LOD, 596 DIRTY_BIT_MAX_LOD, 597 DIRTY_BIT_COMPARE_MODE, 598 DIRTY_BIT_COMPARE_FUNC, 599 DIRTY_BIT_SRGB_DECODE, 600 DIRTY_BIT_SRGB_OVERRIDE, 601 DIRTY_BIT_BORDER_COLOR, 602 603 // Texture state 604 DIRTY_BIT_SWIZZLE_RED, 605 DIRTY_BIT_SWIZZLE_GREEN, 606 DIRTY_BIT_SWIZZLE_BLUE, 607 DIRTY_BIT_SWIZZLE_ALPHA, 608 DIRTY_BIT_BASE_LEVEL, 609 DIRTY_BIT_MAX_LEVEL, 610 DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE, 611 612 // Image state 613 DIRTY_BIT_BOUND_AS_IMAGE, 614 DIRTY_BIT_BOUND_AS_ATTACHMENT, 615 616 // Misc 617 DIRTY_BIT_USAGE, 618 DIRTY_BIT_IMPLEMENTATION, 619 620 DIRTY_BIT_COUNT, 621 }; 622 using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>; 623 624 angle::Result syncState(const Context *context, Command source); hasAnyDirtyBit()625 bool hasAnyDirtyBit() const { return mDirtyBits.any(); } hasAnyDirtyBitExcludingBoundAsAttachmentBit()626 bool hasAnyDirtyBitExcludingBoundAsAttachmentBit() const 627 { 628 static constexpr DirtyBits kBoundAsAttachment = DirtyBits({DIRTY_BIT_BOUND_AS_ATTACHMENT}); 629 return mDirtyBits.any() && mDirtyBits != kBoundAsAttachment; 630 } 631 632 // ObserverInterface implementation. 633 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 634 635 private: 636 rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; 637 638 // ANGLE-only method, used internally 639 friend class egl::Surface; 640 angle::Result bindTexImageFromSurface(Context *context, egl::Surface *surface); 641 angle::Result releaseTexImageFromSurface(const Context *context); 642 643 // ANGLE-only methods, used internally 644 friend class egl::Stream; 645 void bindStream(egl::Stream *stream); 646 void releaseStream(); 647 angle::Result acquireImageFromStream(const Context *context, 648 const egl::Stream::GLTextureDescription &desc); 649 angle::Result releaseImageFromStream(const Context *context); 650 651 void invalidateCompletenessCache() const; 652 angle::Result releaseTexImageInternal(Context *context); 653 654 bool doesSubImageNeedInit(const Context *context, 655 const ImageIndex &imageIndex, 656 const Box &area) const; 657 angle::Result ensureSubImageInitialized(const Context *context, 658 const ImageIndex &imageIndex, 659 const Box &area); 660 661 angle::Result handleMipmapGenerationHint(Context *context, int level); 662 663 void signalDirtyState(size_t dirtyBit); 664 665 TextureState mState; 666 DirtyBits mDirtyBits; 667 rx::TextureImpl *mTexture; 668 angle::ObserverBinding mImplObserver; 669 // For EXT_texture_buffer, observes buffer changes. 670 angle::ObserverBinding mBufferObserver; 671 672 egl::Surface *mBoundSurface; 673 egl::Stream *mBoundStream; 674 675 // We track all the serials of the Framebuffers this texture is attached to. Note that this 676 // allows duplicates because different ranges of a Texture can be bound to the same Framebuffer. 677 // For the purposes of depth-stencil loops, a simple "isBound" check works fine. For color 678 // attachment Feedback Loop checks we then need to check further to see when a Texture is bound 679 // to mulitple bindings that the bindings don't overlap. 680 static constexpr uint32_t kFastFramebufferSerialCount = 8; 681 angle::FastVector<rx::Serial, kFastFramebufferSerialCount> mBoundFramebufferSerials; 682 683 struct SamplerCompletenessCache 684 { 685 SamplerCompletenessCache(); 686 687 // Context used to generate this cache entry 688 ContextID context; 689 690 // All values that affect sampler completeness that are not stored within 691 // the texture itself 692 SamplerState samplerState; 693 694 // Result of the sampler completeness with the above parameters 695 bool samplerComplete; 696 }; 697 698 mutable SamplerCompletenessCache mCompletenessCache; 699 }; 700 701 inline bool operator==(const TextureState &a, const TextureState &b) 702 { 703 return a.mSwizzleState == b.mSwizzleState && a.mSamplerState == b.mSamplerState && 704 a.mBaseLevel == b.mBaseLevel && a.mMaxLevel == b.mMaxLevel && 705 a.mImmutableFormat == b.mImmutableFormat && a.mImmutableLevels == b.mImmutableLevels && 706 a.mUsage == b.mUsage; 707 } 708 709 inline bool operator!=(const TextureState &a, const TextureState &b) 710 { 711 return !(a == b); 712 } 713 } // namespace gl 714 715 #endif // LIBANGLE_TEXTURE_H_ 716