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; } renderabilityValidation()147 bool renderabilityValidation() const { return mRenderabilityValidation; } getDepthStencilTextureMode()148 GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; } 149 hasBeenBoundAsImage()150 bool hasBeenBoundAsImage() const { return mHasBeenBoundAsImage; } hasBeenBoundAsAttachment()151 bool hasBeenBoundAsAttachment() const { return mHasBeenBoundAsAttachment; } hasBeenBoundToMSRTTFramebuffer()152 bool hasBeenBoundToMSRTTFramebuffer() const { return mHasBeenBoundToMSRTTFramebuffer; } 153 getSRGBOverride()154 gl::SrgbOverride getSRGBOverride() const { return mSrgbOverride; } 155 156 // Returns the desc of the base level. Only valid for cube-complete/mip-complete textures. 157 const ImageDesc &getBaseLevelDesc() const; 158 const ImageDesc &getLevelZeroDesc() const; 159 160 // This helper is used by backends that require special setup to read stencil data isStencilMode()161 bool isStencilMode() const 162 { 163 const GLenum format = 164 getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel()).format.info->format; 165 return (format == GL_DEPTH_STENCIL) ? (mDepthStencilTextureMode == GL_STENCIL_INDEX) 166 : (format == GL_STENCIL_INDEX); 167 } 168 169 // GLES1 emulation: For GL_OES_draw_texture 170 void setCrop(const Rectangle &rect); 171 const Rectangle &getCrop() const; 172 173 // GLES1 emulation: Auto-mipmap generation is a texparameter 174 void setGenerateMipmapHint(GLenum hint); 175 GLenum getGenerateMipmapHint() const; 176 177 // Return the enabled mipmap level count. 178 GLuint getEnabledLevelCount() const; 179 getImmutableFormat()180 bool getImmutableFormat() const { return mImmutableFormat; } getImmutableLevels()181 GLuint getImmutableLevels() const { return mImmutableLevels; } 182 getImageDescs()183 const std::vector<ImageDesc> &getImageDescs() const { return mImageDescs; } 184 getInitState()185 InitState getInitState() const { return mInitState; } 186 getBuffer()187 const OffsetBindingPointer<Buffer> &getBuffer() const { return mBuffer; } 188 getLabel()189 const std::string &getLabel() const { return mLabel; } 190 getTilingMode()191 gl::TilingMode getTilingMode() const { return mTilingMode; } 192 isInternalIncompleteTexture()193 bool isInternalIncompleteTexture() const { return mIsInternalIncompleteTexture; } 194 getFoveationState()195 const FoveationState &getFoveationState() const { return mFoveationState; } 196 getSurfaceCompressionFixedRate()197 GLenum getSurfaceCompressionFixedRate() const { return mCompressionFixedRate; } 198 199 private: 200 // Texture needs access to the ImageDesc functions. 201 friend class Texture; 202 friend bool operator==(const TextureState &a, const TextureState &b); 203 204 bool computeSamplerCompleteness(const SamplerState &samplerState, const State &state) const; 205 bool computeSamplerCompletenessForCopyImage(const SamplerState &samplerState, 206 const State &state) const; 207 208 bool computeMipmapCompleteness() const; 209 bool computeLevelCompleteness(TextureTarget target, size_t level) const; 210 SamplerFormat computeRequiredSamplerFormat(const SamplerState &samplerState) const; 211 212 TextureTarget getBaseImageTarget() const; 213 214 void setImageDesc(TextureTarget target, size_t level, const ImageDesc &desc); 215 void setImageDescChain(GLuint baselevel, 216 GLuint maxLevel, 217 Extents baseSize, 218 const Format &format, 219 InitState initState); 220 void setImageDescChainMultisample(Extents baseSize, 221 const Format &format, 222 GLsizei samples, 223 bool fixedSampleLocations, 224 InitState initState); 225 226 void clearImageDesc(TextureTarget target, size_t level); 227 void clearImageDescs(); 228 229 const TextureType mType; 230 231 SwizzleState mSwizzleState; 232 233 SamplerState mSamplerState; 234 235 SrgbOverride mSrgbOverride; 236 237 GLuint mBaseLevel; 238 GLuint mMaxLevel; 239 240 GLenum mDepthStencilTextureMode; 241 242 // Distinguish internally created textures. The Vulkan backend avoids initializing them from an 243 // unlocked tail call because they are lazily created on draw, and we don't want to add the 244 // overhead of tail-call checks to draw calls. 245 bool mIsInternalIncompleteTexture; 246 247 bool mHasBeenBoundAsImage; 248 bool mHasBeenBoundAsAttachment; 249 bool mHasBeenBoundToMSRTTFramebuffer; 250 251 bool mImmutableFormat; 252 GLuint mImmutableLevels; 253 254 // From GL_ANGLE_texture_usage 255 GLenum mUsage; 256 257 // GL_EXT_protected_textures 258 bool mHasProtectedContent; 259 260 bool mRenderabilityValidation; 261 262 // GL_EXT_memory_object 263 gl::TilingMode mTilingMode; 264 265 std::vector<ImageDesc> mImageDescs; 266 267 // GLES1 emulation: Texture crop rectangle 268 // For GL_OES_draw_texture 269 Rectangle mCropRect; 270 271 // GLES1 emulation: Generate-mipmap hint per texture 272 GLenum mGenerateMipmapHint; 273 274 // GL_OES_texture_buffer / GLES3.2 275 OffsetBindingPointer<Buffer> mBuffer; 276 277 InitState mInitState; 278 279 mutable SamplerFormat mCachedSamplerFormat; 280 mutable GLenum mCachedSamplerCompareMode; 281 mutable bool mCachedSamplerFormatValid; 282 std::string mLabel; 283 284 // GL_QCOM_texture_foveated 285 FoveationState mFoveationState; 286 287 // GL_EXT_texture_storage_compression 288 GLenum mCompressionFixedRate; 289 }; 290 291 bool operator==(const TextureState &a, const TextureState &b); 292 bool operator!=(const TextureState &a, const TextureState &b); 293 294 class TextureBufferContentsObservers final : angle::NonCopyable 295 { 296 public: 297 TextureBufferContentsObservers(Texture *texture); 298 void enableForBuffer(Buffer *buffer); 299 void disableForBuffer(Buffer *buffer); 300 bool isEnabledForBuffer(Buffer *buffer); 301 302 private: 303 Texture *mTexture; 304 }; 305 306 class Texture final : public RefCountObject<TextureID>, 307 public egl::ImageSibling, 308 public LabeledObject 309 { 310 public: 311 Texture(rx::GLImplFactory *factory, TextureID id, TextureType type); 312 ~Texture() override; 313 314 void onDestroy(const Context *context) override; 315 316 angle::Result setLabel(const Context *context, const std::string &label) override; 317 318 const std::string &getLabel() const override; 319 getType()320 TextureType getType() const { return mState.mType; } 321 322 void setSwizzleRed(const Context *context, GLenum swizzleRed); 323 GLenum getSwizzleRed() const; 324 325 void setSwizzleGreen(const Context *context, GLenum swizzleGreen); 326 GLenum getSwizzleGreen() const; 327 328 void setSwizzleBlue(const Context *context, GLenum swizzleBlue); 329 GLenum getSwizzleBlue() const; 330 331 void setSwizzleAlpha(const Context *context, GLenum swizzleAlpha); 332 GLenum getSwizzleAlpha() const; 333 334 void setMinFilter(const Context *context, GLenum minFilter); 335 GLenum getMinFilter() const; 336 337 void setMagFilter(const Context *context, GLenum magFilter); 338 GLenum getMagFilter() const; 339 340 void setWrapS(const Context *context, GLenum wrapS); 341 GLenum getWrapS() const; 342 343 void setWrapT(const Context *context, GLenum wrapT); 344 GLenum getWrapT() const; 345 346 void setWrapR(const Context *context, GLenum wrapR); 347 GLenum getWrapR() const; 348 349 void setMaxAnisotropy(const Context *context, float maxAnisotropy); 350 float getMaxAnisotropy() const; 351 352 void setMinLod(const Context *context, GLfloat minLod); 353 GLfloat getMinLod() const; 354 355 void setMaxLod(const Context *context, GLfloat maxLod); 356 GLfloat getMaxLod() const; 357 358 void setCompareMode(const Context *context, GLenum compareMode); 359 GLenum getCompareMode() const; 360 361 void setCompareFunc(const Context *context, GLenum compareFunc); 362 GLenum getCompareFunc() const; 363 364 void setSRGBDecode(const Context *context, GLenum sRGBDecode); 365 GLenum getSRGBDecode() const; 366 367 void setSRGBOverride(const Context *context, GLenum sRGBOverride); 368 GLenum getSRGBOverride() const; 369 370 const SamplerState &getSamplerState() const; 371 372 angle::Result setBaseLevel(const Context *context, GLuint baseLevel); 373 GLuint getBaseLevel() const; 374 375 void setMaxLevel(const Context *context, GLuint maxLevel); 376 GLuint getMaxLevel() const; 377 378 void setDepthStencilTextureMode(const Context *context, GLenum mode); 379 GLenum getDepthStencilTextureMode() const; 380 381 bool getImmutableFormat() const; 382 383 GLuint getImmutableLevels() const; 384 385 void setUsage(const Context *context, GLenum usage); 386 GLenum getUsage() const; 387 388 void setProtectedContent(Context *context, bool hasProtectedContent); 389 bool hasProtectedContent() const override; hasFoveatedRendering()390 bool hasFoveatedRendering() const override { return isFoveationEnabled(); } getFoveationState()391 const gl::FoveationState *getFoveationState() const override { return &mState.mFoveationState; } 392 393 void setRenderabilityValidation(Context *context, bool renderabilityValidation); 394 395 void setTilingMode(Context *context, GLenum tilingMode); 396 GLenum getTilingMode() const; 397 getState()398 const TextureState &getState() const { return mState; } 399 400 void setBorderColor(const Context *context, const ColorGeneric &color); 401 const ColorGeneric &getBorderColor() const; 402 403 angle::Result setBuffer(const Context *context, gl::Buffer *buffer, GLenum internalFormat); 404 angle::Result setBufferRange(const Context *context, 405 gl::Buffer *buffer, 406 GLenum internalFormat, 407 GLintptr offset, 408 GLsizeiptr size); 409 const OffsetBindingPointer<Buffer> &getBuffer() const; 410 411 GLint getRequiredTextureImageUnits(const Context *context) const; 412 413 const TextureState &getTextureState() const; 414 415 const Extents &getExtents(TextureTarget target, size_t level) const; 416 size_t getWidth(TextureTarget target, size_t level) const; 417 size_t getHeight(TextureTarget target, size_t level) const; 418 size_t getDepth(TextureTarget target, size_t level) const; 419 GLsizei getSamples(TextureTarget target, size_t level) const; 420 bool getFixedSampleLocations(TextureTarget target, size_t level) const; 421 const Format &getFormat(TextureTarget target, size_t level) const; 422 423 // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10. 424 GLuint getMipmapMaxLevel() const; 425 426 bool isMipmapComplete() const; 427 428 void setFoveatedFeatureBits(const GLuint features); 429 GLuint getFoveatedFeatureBits() const; 430 bool isFoveationEnabled() const; 431 GLuint getSupportedFoveationFeatures() const; 432 getNumFocalPoints()433 GLuint getNumFocalPoints() const { return mState.mFoveationState.getMaxNumFocalPoints(); } 434 void setMinPixelDensity(const GLfloat density); 435 GLfloat getMinPixelDensity() const; 436 void setFocalPoint(uint32_t layer, 437 uint32_t focalPointIndex, 438 float focalX, 439 float focalY, 440 float gainX, 441 float gainY, 442 float foveaArea); 443 const FocalPoint &getFocalPoint(uint32_t layer, uint32_t focalPoint) const; 444 445 GLint getImageCompressionRate(const Context *context) const; 446 GLint getFormatSupportedCompressionRates(const Context *context, 447 GLenum internalformat, 448 GLsizei bufSize, 449 GLint *rates) const; 450 451 angle::Result setImage(Context *context, 452 const PixelUnpackState &unpackState, 453 Buffer *unpackBuffer, 454 TextureTarget target, 455 GLint level, 456 GLenum internalFormat, 457 const Extents &size, 458 GLenum format, 459 GLenum type, 460 const uint8_t *pixels); 461 angle::Result setSubImage(Context *context, 462 const PixelUnpackState &unpackState, 463 Buffer *unpackBuffer, 464 TextureTarget target, 465 GLint level, 466 const Box &area, 467 GLenum format, 468 GLenum type, 469 const uint8_t *pixels); 470 471 angle::Result setCompressedImage(Context *context, 472 const PixelUnpackState &unpackState, 473 TextureTarget target, 474 GLint level, 475 GLenum internalFormat, 476 const Extents &size, 477 size_t imageSize, 478 const uint8_t *pixels); 479 angle::Result setCompressedSubImage(const Context *context, 480 const PixelUnpackState &unpackState, 481 TextureTarget target, 482 GLint level, 483 const Box &area, 484 GLenum format, 485 size_t imageSize, 486 const uint8_t *pixels); 487 488 angle::Result copyImage(Context *context, 489 TextureTarget target, 490 GLint level, 491 const Rectangle &sourceArea, 492 GLenum internalFormat, 493 Framebuffer *source); 494 angle::Result copySubImage(Context *context, 495 const ImageIndex &index, 496 const Offset &destOffset, 497 const Rectangle &sourceArea, 498 Framebuffer *source); 499 500 angle::Result copyRenderbufferSubData(Context *context, 501 const gl::Renderbuffer *srcBuffer, 502 GLint srcLevel, 503 GLint srcX, 504 GLint srcY, 505 GLint srcZ, 506 GLint dstLevel, 507 GLint dstX, 508 GLint dstY, 509 GLint dstZ, 510 GLsizei srcWidth, 511 GLsizei srcHeight, 512 GLsizei srcDepth); 513 514 angle::Result copyTextureSubData(Context *context, 515 const gl::Texture *srcTexture, 516 GLint srcLevel, 517 GLint srcX, 518 GLint srcY, 519 GLint srcZ, 520 GLint dstLevel, 521 GLint dstX, 522 GLint dstY, 523 GLint dstZ, 524 GLsizei srcWidth, 525 GLsizei srcHeight, 526 GLsizei srcDepth); 527 528 angle::Result copyTexture(Context *context, 529 TextureTarget target, 530 GLint level, 531 GLenum internalFormat, 532 GLenum type, 533 GLint sourceLevel, 534 bool unpackFlipY, 535 bool unpackPremultiplyAlpha, 536 bool unpackUnmultiplyAlpha, 537 Texture *source); 538 angle::Result copySubTexture(const Context *context, 539 TextureTarget target, 540 GLint level, 541 const Offset &destOffset, 542 GLint sourceLevel, 543 const Box &sourceBox, 544 bool unpackFlipY, 545 bool unpackPremultiplyAlpha, 546 bool unpackUnmultiplyAlpha, 547 Texture *source); 548 angle::Result copyCompressedTexture(Context *context, const Texture *source); 549 550 angle::Result setStorage(Context *context, 551 TextureType type, 552 GLsizei levels, 553 GLenum internalFormat, 554 const Extents &size); 555 556 angle::Result setStorageMultisample(Context *context, 557 TextureType type, 558 GLsizei samplesIn, 559 GLint internalformat, 560 const Extents &size, 561 bool fixedSampleLocations); 562 563 angle::Result setStorageExternalMemory(Context *context, 564 TextureType type, 565 GLsizei levels, 566 GLenum internalFormat, 567 const Extents &size, 568 MemoryObject *memoryObject, 569 GLuint64 offset, 570 GLbitfield createFlags, 571 GLbitfield usageFlags, 572 const void *imageCreateInfoPNext); 573 574 angle::Result setImageExternal(Context *context, 575 TextureTarget target, 576 GLint level, 577 GLenum internalFormat, 578 const Extents &size, 579 GLenum format, 580 GLenum type); 581 582 angle::Result setEGLImageTarget(Context *context, TextureType type, egl::Image *imageTarget); 583 584 angle::Result setStorageEGLImageTarget(Context *context, 585 TextureType type, 586 egl::Image *image, 587 const GLint *attrib_list); 588 589 angle::Result setStorageAttribs(Context *context, 590 TextureType type, 591 GLsizei levels, 592 GLenum internalFormat, 593 const Extents &size, 594 const GLint *attribList); 595 596 angle::Result generateMipmap(Context *context); 597 598 angle::Result clearImage(Context *context, 599 GLint level, 600 GLenum format, 601 GLenum type, 602 const uint8_t *data); 603 angle::Result clearSubImage(Context *context, 604 GLint level, 605 const Box &area, 606 GLenum format, 607 GLenum type, 608 const uint8_t *data); 609 610 void onBindAsImageTexture(); 611 612 egl::Surface *getBoundSurface() const; 613 egl::Stream *getBoundStream() const; 614 615 GLint getMemorySize() const; 616 GLint getLevelMemorySize(TextureTarget target, GLint level) const; 617 618 void signalDirtyStorage(InitState initState); 619 620 bool isSamplerComplete(const Context *context, const Sampler *optionalSampler); 621 bool isSamplerCompleteForCopyImage(const Context *context, 622 const Sampler *optionalSampler) const; 623 624 GLenum getImplementationColorReadFormat(const Context *context) const; 625 GLenum getImplementationColorReadType(const Context *context) const; 626 627 // We pass the pack buffer and state explicitly so they can be overridden during capture. 628 angle::Result getTexImage(const Context *context, 629 const PixelPackState &packState, 630 Buffer *packBuffer, 631 TextureTarget target, 632 GLint level, 633 GLenum format, 634 GLenum type, 635 void *pixels); 636 637 angle::Result getCompressedTexImage(const Context *context, 638 const PixelPackState &packState, 639 Buffer *packBuffer, 640 TextureTarget target, 641 GLint level, 642 void *pixels); 643 getImplementation()644 rx::TextureImpl *getImplementation() const { return mTexture; } 645 646 // FramebufferAttachmentObject implementation 647 Extents getAttachmentSize(const ImageIndex &imageIndex) const override; 648 Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override; 649 GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override; 650 bool isRenderable(const Context *context, 651 GLenum binding, 652 const ImageIndex &imageIndex) const override; 653 654 bool getAttachmentFixedSampleLocations(const ImageIndex &imageIndex) const; 655 656 // GLES1 emulation 657 void setCrop(const Rectangle &rect); 658 const Rectangle &getCrop() const; 659 void setGenerateMipmapHint(GLenum generate); 660 GLenum getGenerateMipmapHint() const; 661 662 void onAttach(const Context *context, rx::UniqueSerial framebufferSerial) override; 663 void onDetach(const Context *context, rx::UniqueSerial framebufferSerial) override; 664 665 // Used specifically for FramebufferAttachmentObject. 666 GLuint getId() const override; 667 668 GLuint getNativeID() const; 669 670 // Needed for robust resource init. 671 angle::Result ensureInitialized(const Context *context); 672 InitState initState(GLenum binding, const ImageIndex &imageIndex) const override; initState()673 InitState initState() const { return mState.mInitState; } 674 void setInitState(GLenum binding, const ImageIndex &imageIndex, InitState initState) override; 675 void setInitState(InitState initState); 676 isBoundToFramebuffer(rx::UniqueSerial framebufferSerial)677 bool isBoundToFramebuffer(rx::UniqueSerial framebufferSerial) const 678 { 679 for (size_t index = 0; index < mBoundFramebufferSerials.size(); ++index) 680 { 681 if (mBoundFramebufferSerials[index] == framebufferSerial) 682 return true; 683 } 684 685 return false; 686 } 687 isDepthOrStencil()688 bool isDepthOrStencil() const 689 { 690 return mState.getBaseLevelDesc().format.info->isDepthOrStencil(); 691 } 692 693 enum DirtyBitType 694 { 695 // Sampler state 696 DIRTY_BIT_MIN_FILTER, 697 DIRTY_BIT_MAG_FILTER, 698 DIRTY_BIT_WRAP_S, 699 DIRTY_BIT_WRAP_T, 700 DIRTY_BIT_WRAP_R, 701 DIRTY_BIT_MAX_ANISOTROPY, 702 DIRTY_BIT_MIN_LOD, 703 DIRTY_BIT_MAX_LOD, 704 DIRTY_BIT_COMPARE_MODE, 705 DIRTY_BIT_COMPARE_FUNC, 706 DIRTY_BIT_SRGB_DECODE, 707 DIRTY_BIT_SRGB_OVERRIDE, 708 DIRTY_BIT_BORDER_COLOR, 709 710 // Texture state 711 DIRTY_BIT_SWIZZLE_RED, 712 DIRTY_BIT_SWIZZLE_GREEN, 713 DIRTY_BIT_SWIZZLE_BLUE, 714 DIRTY_BIT_SWIZZLE_ALPHA, 715 DIRTY_BIT_BASE_LEVEL, 716 DIRTY_BIT_MAX_LEVEL, 717 DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE, 718 DIRTY_BIT_RENDERABILITY_VALIDATION_ANGLE, 719 720 // Image state 721 DIRTY_BIT_BOUND_AS_IMAGE, 722 DIRTY_BIT_BOUND_AS_ATTACHMENT, 723 724 // Bound to MSRTT Framebuffer 725 DIRTY_BIT_BOUND_TO_MSRTT_FRAMEBUFFER, 726 727 // Misc 728 DIRTY_BIT_USAGE, 729 DIRTY_BIT_IMPLEMENTATION, 730 731 DIRTY_BIT_COUNT, 732 }; 733 using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>; 734 735 angle::Result syncState(const Context *context, Command source); hasAnyDirtyBit()736 bool hasAnyDirtyBit() const { return mDirtyBits.any(); } hasAnyDirtyBitExcludingBoundAsAttachmentBit()737 bool hasAnyDirtyBitExcludingBoundAsAttachmentBit() const 738 { 739 static constexpr DirtyBits kBoundAsAttachment = DirtyBits({DIRTY_BIT_BOUND_AS_ATTACHMENT}); 740 return mDirtyBits.any() && mDirtyBits != kBoundAsAttachment; 741 } 742 743 // ObserverInterface implementation. 744 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 745 746 // Texture buffer updates. 747 void onBufferContentsChange(); 748 markInternalIncompleteTexture()749 void markInternalIncompleteTexture() { mState.mIsInternalIncompleteTexture = true; } 750 751 // Texture bound to MSRTT framebuffer. 752 void onBindToMSRTTFramebuffer(); 753 754 private: 755 rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; 756 757 // ANGLE-only method, used internally 758 friend class egl::Surface; 759 angle::Result bindTexImageFromSurface(Context *context, egl::Surface *surface); 760 angle::Result releaseTexImageFromSurface(const Context *context); 761 762 // ANGLE-only methods, used internally 763 friend class egl::Stream; 764 void bindStream(egl::Stream *stream); 765 void releaseStream(); 766 angle::Result acquireImageFromStream(const Context *context, 767 const egl::Stream::GLTextureDescription &desc); 768 angle::Result releaseImageFromStream(const Context *context); 769 770 void invalidateCompletenessCache() const; 771 angle::Result releaseTexImageInternal(Context *context); 772 773 bool doesSubImageNeedInit(const Context *context, 774 const ImageIndex &imageIndex, 775 const Box &area) const; 776 angle::Result ensureSubImageInitialized(const Context *context, 777 const ImageIndex &imageIndex, 778 const Box &area); 779 780 angle::Result handleMipmapGenerationHint(Context *context, int level); 781 782 angle::Result setEGLImageTargetImpl(Context *context, 783 TextureType type, 784 GLuint levels, 785 egl::Image *imageTarget); 786 787 void signalDirtyState(size_t dirtyBit); 788 789 TextureState mState; 790 DirtyBits mDirtyBits; 791 rx::TextureImpl *mTexture; 792 angle::ObserverBinding mImplObserver; 793 // For EXT_texture_buffer, observes buffer changes. 794 angle::ObserverBinding mBufferObserver; 795 796 egl::Surface *mBoundSurface; 797 egl::Stream *mBoundStream; 798 799 // We track all the serials of the Framebuffers this texture is attached to. Note that this 800 // allows duplicates because different ranges of a Texture can be bound to the same Framebuffer. 801 // For the purposes of depth-stencil loops, a simple "isBound" check works fine. For color 802 // attachment Feedback Loop checks we then need to check further to see when a Texture is bound 803 // to mulitple bindings that the bindings don't overlap. 804 static constexpr uint32_t kFastFramebufferSerialCount = 8; 805 angle::FastVector<rx::UniqueSerial, kFastFramebufferSerialCount> mBoundFramebufferSerials; 806 807 struct SamplerCompletenessCache 808 { 809 SamplerCompletenessCache(); 810 811 // Context used to generate this cache entry 812 ContextID context; 813 814 // All values that affect sampler completeness that are not stored within 815 // the texture itself 816 SamplerState samplerState; 817 818 // Result of the sampler completeness with the above parameters 819 bool samplerComplete; 820 }; 821 822 mutable SamplerCompletenessCache mCompletenessCache; 823 TextureBufferContentsObservers mBufferContentsObservers; 824 }; 825 826 inline bool operator==(const TextureState &a, const TextureState &b) 827 { 828 return a.mSwizzleState == b.mSwizzleState && a.mSamplerState == b.mSamplerState && 829 a.mBaseLevel == b.mBaseLevel && a.mMaxLevel == b.mMaxLevel && 830 a.mImmutableFormat == b.mImmutableFormat && a.mImmutableLevels == b.mImmutableLevels && 831 a.mUsage == b.mUsage; 832 } 833 834 inline bool operator!=(const TextureState &a, const TextureState &b) 835 { 836 return !(a == b); 837 } 838 } // namespace gl 839 840 #endif // LIBANGLE_TEXTURE_H_ 841