1 // 2 // Copyright 2016 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 // TextureVk.h: 7 // Defines the class interface for TextureVk, implementing TextureImpl. 8 // 9 10 #ifndef LIBANGLE_RENDERER_VULKAN_TEXTUREVK_H_ 11 #define LIBANGLE_RENDERER_VULKAN_TEXTUREVK_H_ 12 13 #include "libANGLE/renderer/TextureImpl.h" 14 #include "libANGLE/renderer/vulkan/RenderTargetVk.h" 15 #include "libANGLE/renderer/vulkan/ResourceVk.h" 16 #include "libANGLE/renderer/vulkan/SamplerVk.h" 17 #include "libANGLE/renderer/vulkan/vk_helpers.h" 18 19 namespace rx 20 { 21 22 enum class ImageMipLevels 23 { 24 EnabledLevels = 0, 25 FullMipChain = 1, 26 27 InvalidEnum = 2, 28 }; 29 30 enum class TextureUpdateResult 31 { 32 ImageUnaffected, 33 ImageRespecified, 34 }; 35 36 class TextureVk : public TextureImpl, public angle::ObserverInterface 37 { 38 public: 39 TextureVk(const gl::TextureState &state, RendererVk *renderer); 40 ~TextureVk() override; 41 void onDestroy(const gl::Context *context) override; 42 43 angle::Result setImage(const gl::Context *context, 44 const gl::ImageIndex &index, 45 GLenum internalFormat, 46 const gl::Extents &size, 47 GLenum format, 48 GLenum type, 49 const gl::PixelUnpackState &unpack, 50 gl::Buffer *unpackBuffer, 51 const uint8_t *pixels) override; 52 angle::Result setSubImage(const gl::Context *context, 53 const gl::ImageIndex &index, 54 const gl::Box &area, 55 GLenum format, 56 GLenum type, 57 const gl::PixelUnpackState &unpack, 58 gl::Buffer *unpackBuffer, 59 const uint8_t *pixels) override; 60 61 angle::Result setCompressedImage(const gl::Context *context, 62 const gl::ImageIndex &index, 63 GLenum internalFormat, 64 const gl::Extents &size, 65 const gl::PixelUnpackState &unpack, 66 size_t imageSize, 67 const uint8_t *pixels) override; 68 angle::Result setCompressedSubImage(const gl::Context *context, 69 const gl::ImageIndex &index, 70 const gl::Box &area, 71 GLenum format, 72 const gl::PixelUnpackState &unpack, 73 size_t imageSize, 74 const uint8_t *pixels) override; 75 76 angle::Result copyImage(const gl::Context *context, 77 const gl::ImageIndex &index, 78 const gl::Rectangle &sourceArea, 79 GLenum internalFormat, 80 gl::Framebuffer *source) override; 81 angle::Result copySubImage(const gl::Context *context, 82 const gl::ImageIndex &index, 83 const gl::Offset &destOffset, 84 const gl::Rectangle &sourceArea, 85 gl::Framebuffer *source) override; 86 87 angle::Result copyTexture(const gl::Context *context, 88 const gl::ImageIndex &index, 89 GLenum internalFormat, 90 GLenum type, 91 GLint sourceLevelGL, 92 bool unpackFlipY, 93 bool unpackPremultiplyAlpha, 94 bool unpackUnmultiplyAlpha, 95 const gl::Texture *source) override; 96 angle::Result copySubTexture(const gl::Context *context, 97 const gl::ImageIndex &index, 98 const gl::Offset &destOffset, 99 GLint sourceLevelGL, 100 const gl::Box &sourceBox, 101 bool unpackFlipY, 102 bool unpackPremultiplyAlpha, 103 bool unpackUnmultiplyAlpha, 104 const gl::Texture *source) override; 105 106 angle::Result copyRenderbufferSubData(const gl::Context *context, 107 const gl::Renderbuffer *srcBuffer, 108 GLint srcLevel, 109 GLint srcX, 110 GLint srcY, 111 GLint srcZ, 112 GLint dstLevel, 113 GLint dstX, 114 GLint dstY, 115 GLint dstZ, 116 GLsizei srcWidth, 117 GLsizei srcHeight, 118 GLsizei srcDepth) override; 119 120 angle::Result copyTextureSubData(const gl::Context *context, 121 const gl::Texture *srcTexture, 122 GLint srcLevel, 123 GLint srcX, 124 GLint srcY, 125 GLint srcZ, 126 GLint dstLevel, 127 GLint dstX, 128 GLint dstY, 129 GLint dstZ, 130 GLsizei srcWidth, 131 GLsizei srcHeight, 132 GLsizei srcDepth) override; 133 134 angle::Result copyCompressedTexture(const gl::Context *context, 135 const gl::Texture *source) override; 136 137 angle::Result setStorage(const gl::Context *context, 138 gl::TextureType type, 139 size_t levels, 140 GLenum internalFormat, 141 const gl::Extents &size) override; 142 143 angle::Result setStorageExternalMemory(const gl::Context *context, 144 gl::TextureType type, 145 size_t levels, 146 GLenum internalFormat, 147 const gl::Extents &size, 148 gl::MemoryObject *memoryObject, 149 GLuint64 offset, 150 GLbitfield createFlags, 151 GLbitfield usageFlags, 152 const void *imageCreateInfoPNext) override; 153 154 angle::Result setEGLImageTarget(const gl::Context *context, 155 gl::TextureType type, 156 egl::Image *image) override; 157 158 angle::Result setImageExternal(const gl::Context *context, 159 gl::TextureType type, 160 egl::Stream *stream, 161 const egl::Stream::GLTextureDescription &desc) override; 162 163 angle::Result setBuffer(const gl::Context *context, GLenum internalFormat) override; 164 165 angle::Result generateMipmap(const gl::Context *context) override; 166 167 angle::Result setBaseLevel(const gl::Context *context, GLuint baseLevel) override; 168 169 angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override; 170 angle::Result releaseTexImage(const gl::Context *context) override; 171 172 angle::Result getAttachmentRenderTarget(const gl::Context *context, 173 GLenum binding, 174 const gl::ImageIndex &imageIndex, 175 GLsizei samples, 176 FramebufferAttachmentRenderTarget **rtOut) override; 177 178 angle::Result syncState(const gl::Context *context, 179 const gl::Texture::DirtyBits &dirtyBits, 180 gl::Command source) override; 181 182 angle::Result setStorageMultisample(const gl::Context *context, 183 gl::TextureType type, 184 GLsizei samples, 185 GLint internalformat, 186 const gl::Extents &size, 187 bool fixedSampleLocations) override; 188 189 angle::Result initializeContents(const gl::Context *context, 190 const gl::ImageIndex &imageIndex) override; 191 getImage()192 const vk::ImageHelper &getImage() const 193 { 194 ASSERT(mImage && mImage->valid()); 195 return *mImage; 196 } 197 getImage()198 vk::ImageHelper &getImage() 199 { 200 ASSERT(mImage && mImage->valid()); 201 return *mImage; 202 } 203 retainBufferViews(vk::ResourceUseList * resourceUseList)204 void retainBufferViews(vk::ResourceUseList *resourceUseList) 205 { 206 mBufferViews.retain(resourceUseList); 207 } 208 209 void releaseOwnershipOfImage(const gl::Context *context); 210 211 const vk::ImageView &getReadImageView(vk::Context *context, 212 GLenum srgbDecode, 213 bool texelFetchStaticUse) const; 214 215 // A special view for cube maps as a 2D array, used with shaders that do texelFetch() and for 216 // seamful cube map emulation. 217 const vk::ImageView &getFetchImageView(vk::Context *context, 218 GLenum srgbDecode, 219 bool texelFetchStaticUse) const; 220 221 angle::Result getBufferViewAndRecordUse(vk::Context *context, 222 const vk::Format *imageUniformFormat, 223 bool isImage, 224 const vk::BufferView **viewOut); 225 226 // A special view used for texture copies that shouldn't perform swizzle. 227 const vk::ImageView &getCopyImageView() const; 228 angle::Result getStorageImageView(vk::Context *context, 229 const gl::ImageUnit &binding, 230 const vk::ImageView **imageViewOut); 231 getSampler()232 const vk::SamplerHelper &getSampler() const 233 { 234 ASSERT(mSampler.valid()); 235 return mSampler.get(); 236 } 237 238 // Normally, initialize the image with enabled mipmap level counts. 239 angle::Result ensureImageInitialized(ContextVk *contextVk, ImageMipLevels mipLevels); 240 getImageViewSubresourceSerial(const gl::SamplerState & samplerState)241 vk::ImageOrBufferViewSubresourceSerial getImageViewSubresourceSerial( 242 const gl::SamplerState &samplerState) const 243 { 244 if (samplerState.getSRGBDecode() == GL_DECODE_EXT) 245 { 246 ASSERT(getImageViewSubresourceSerialImpl(GL_DECODE_EXT) == 247 mCachedImageViewSubresourceSerialSRGBDecode); 248 return mCachedImageViewSubresourceSerialSRGBDecode; 249 } 250 else 251 { 252 ASSERT(getImageViewSubresourceSerialImpl(GL_SKIP_DECODE_EXT) == 253 mCachedImageViewSubresourceSerialSkipDecode); 254 return mCachedImageViewSubresourceSerialSkipDecode; 255 } 256 } 257 258 vk::ImageOrBufferViewSubresourceSerial getBufferViewSerial() const; 259 260 GLenum getColorReadFormat(const gl::Context *context) override; 261 GLenum getColorReadType(const gl::Context *context) override; 262 263 angle::Result getTexImage(const gl::Context *context, 264 const gl::PixelPackState &packState, 265 gl::Buffer *packBuffer, 266 gl::TextureTarget target, 267 GLint level, 268 GLenum format, 269 GLenum type, 270 void *pixels) override; 271 272 angle::Result getCompressedTexImage(const gl::Context *context, 273 const gl::PixelPackState &packState, 274 gl::Buffer *packBuffer, 275 gl::TextureTarget target, 276 GLint level, 277 void *pixels) override; 278 hasBeenBoundAsImage()279 ANGLE_INLINE bool hasBeenBoundAsImage() const { return mState.hasBeenBoundAsImage(); } getBuffer()280 ANGLE_INLINE const gl::OffsetBindingPointer<gl::Buffer> &getBuffer() const 281 { 282 return mState.getBuffer(); 283 } 284 isSRGBOverrideEnabled()285 bool isSRGBOverrideEnabled() const 286 { 287 return mState.getSRGBOverride() != gl::SrgbOverride::Default; 288 } 289 290 angle::Result ensureMutable(ContextVk *contextVk); 291 angle::Result ensureRenderable(ContextVk *contextVk, TextureUpdateResult *updateResultOut); 292 getAndResetImmutableSamplerDirtyState()293 bool getAndResetImmutableSamplerDirtyState() 294 { 295 bool isDirty = mImmutableSamplerDirty; 296 mImmutableSamplerDirty = false; 297 return isDirty; 298 } 299 300 private: 301 // Transform an image index from the frontend into one that can be used on the backing 302 // ImageHelper, taking into account mipmap or cube face offsets 303 gl::ImageIndex getNativeImageIndex(const gl::ImageIndex &inputImageIndex) const; 304 gl::LevelIndex getNativeImageLevel(gl::LevelIndex frontendLevel) const; 305 uint32_t getNativeImageLayer(uint32_t frontendLayer) const; 306 307 // Get the layer count for views. 308 uint32_t getImageViewLayerCount() const; 309 // Get the level count for views. 310 uint32_t getImageViewLevelCount() const; 311 312 void releaseAndDeleteImageAndViews(ContextVk *contextVk); 313 angle::Result ensureImageAllocated(ContextVk *contextVk, const vk::Format &format); 314 void setImageHelper(ContextVk *contextVk, 315 vk::ImageHelper *imageHelper, 316 gl::TextureType imageType, 317 const vk::Format &format, 318 uint32_t imageLevelOffset, 319 uint32_t imageLayerOffset, 320 bool selfOwned); 321 getImageViews()322 vk::ImageViewHelper &getImageViews() 323 { 324 return mMultisampledImageViews[gl::RenderToTextureImageIndex::Default]; 325 } getImageViews()326 const vk::ImageViewHelper &getImageViews() const 327 { 328 return mMultisampledImageViews[gl::RenderToTextureImageIndex::Default]; 329 } 330 331 // Redefine a mip level of the texture. If the new size and format don't match the allocated 332 // image, the image may be released. When redefining a mip of a multi-level image, updates are 333 // forced to be staged, as another mip of the image may be bound to a framebuffer. For example, 334 // assume texture has two mips, and framebuffer is bound to mip 0. Redefining mip 1 to an 335 // incompatible size shouldn't affect the framebuffer, especially if the redefinition comes from 336 // something like glCopyTexSubImage2D() (which simultaneously is reading from said framebuffer, 337 // i.e. mip 0 of the texture). 338 angle::Result redefineLevel(const gl::Context *context, 339 const gl::ImageIndex &index, 340 const vk::Format &format, 341 const gl::Extents &size); 342 343 angle::Result setImageImpl(const gl::Context *context, 344 const gl::ImageIndex &index, 345 const gl::InternalFormat &formatInfo, 346 const gl::Extents &size, 347 GLenum type, 348 const gl::PixelUnpackState &unpack, 349 gl::Buffer *unpackBuffer, 350 const uint8_t *pixels); 351 angle::Result setSubImageImpl(const gl::Context *context, 352 const gl::ImageIndex &index, 353 const gl::Box &area, 354 const gl::InternalFormat &formatInfo, 355 GLenum type, 356 const gl::PixelUnpackState &unpack, 357 gl::Buffer *unpackBuffer, 358 const uint8_t *pixels, 359 const vk::Format &vkFormat); 360 361 angle::Result copyImageDataToBufferAndGetData(ContextVk *contextVk, 362 gl::LevelIndex sourceLevelGL, 363 uint32_t layerCount, 364 const gl::Box &sourceArea, 365 RenderPassClosureReason reason, 366 vk::BufferHelper *copyBuffer, 367 uint8_t **outDataPtr); 368 369 angle::Result copyBufferDataToImage(ContextVk *contextVk, 370 vk::BufferHelper *srcBuffer, 371 const gl::ImageIndex index, 372 uint32_t rowLength, 373 uint32_t imageHeight, 374 const gl::Box &sourceArea, 375 size_t offset, 376 VkImageAspectFlags aspectFlags); 377 378 // Called from syncState to prepare the image for mipmap generation. 379 void prepareForGenerateMipmap(ContextVk *contextVk); 380 381 // Generate mipmaps from level 0 into the rest of the mips. This requires the image to have 382 // STORAGE usage. 383 angle::Result generateMipmapsWithCompute(ContextVk *contextVk); 384 385 angle::Result generateMipmapsWithCPU(const gl::Context *context); 386 387 angle::Result generateMipmapLevelsWithCPU(ContextVk *contextVk, 388 const angle::Format &sourceFormat, 389 GLuint layer, 390 gl::LevelIndex firstMipLevel, 391 gl::LevelIndex maxMipLevel, 392 const size_t sourceWidth, 393 const size_t sourceHeight, 394 const size_t sourceDepth, 395 const size_t sourceRowPitch, 396 const size_t sourceDepthPitch, 397 uint8_t *sourceData); 398 399 angle::Result copySubImageImpl(const gl::Context *context, 400 const gl::ImageIndex &index, 401 const gl::Offset &destOffset, 402 const gl::Rectangle &sourceArea, 403 const gl::InternalFormat &internalFormat, 404 gl::Framebuffer *source); 405 406 angle::Result copySubTextureImpl(ContextVk *contextVk, 407 const gl::ImageIndex &index, 408 const gl::Offset &dstOffset, 409 const gl::InternalFormat &dstFormat, 410 gl::LevelIndex sourceLevelGL, 411 const gl::Box &sourceBox, 412 bool unpackFlipY, 413 bool unpackPremultiplyAlpha, 414 bool unpackUnmultiplyAlpha, 415 TextureVk *source); 416 417 angle::Result copySubImageImplWithTransfer(ContextVk *contextVk, 418 const gl::ImageIndex &index, 419 const gl::Offset &dstOffset, 420 const vk::Format &dstFormat, 421 gl::LevelIndex sourceLevelGL, 422 size_t sourceLayer, 423 const gl::Box &sourceBox, 424 vk::ImageHelper *srcImage); 425 426 angle::Result copySubImageImplWithDraw(ContextVk *contextVk, 427 const gl::ImageIndex &index, 428 const gl::Offset &dstOffset, 429 const vk::Format &dstFormat, 430 gl::LevelIndex sourceLevelGL, 431 const gl::Box &sourceBox, 432 bool isSrcFlipY, 433 bool unpackFlipY, 434 bool unpackPremultiplyAlpha, 435 bool unpackUnmultiplyAlpha, 436 vk::ImageHelper *srcImage, 437 const vk::ImageView *srcView, 438 SurfaceRotation srcFramebufferRotation); 439 440 angle::Result initImage(ContextVk *contextVk, 441 angle::FormatID intendedImageFormatID, 442 angle::FormatID actualImageFormatID, 443 ImageMipLevels mipLevels); 444 void releaseImage(ContextVk *contextVk); 445 void releaseImageViews(ContextVk *contextVk); 446 void releaseStagedUpdates(ContextVk *contextVk); 447 uint32_t getMipLevelCount(ImageMipLevels mipLevels) const; 448 uint32_t getMaxLevelCount() const; 449 angle::Result copyAndStageImageData(ContextVk *contextVk, 450 gl::LevelIndex previousFirstAllocateLevel, 451 vk::ImageHelper *srcImage, 452 vk::ImageHelper *dstImage); 453 angle::Result reinitImageAsRenderable(ContextVk *contextVk, 454 const vk::Format &format, 455 gl::TexLevelMask skipLevelsMask); 456 angle::Result initImageViews(ContextVk *contextVk, 457 const angle::Format &format, 458 const bool sized, 459 uint32_t levelCount, 460 uint32_t layerCount); 461 void initSingleLayerRenderTargets(ContextVk *contextVk, 462 GLuint layerCount, 463 gl::LevelIndex levelIndexGL, 464 gl::RenderToTextureImageIndex renderToTextureIndex); 465 RenderTargetVk *getMultiLayerRenderTarget(ContextVk *contextVk, 466 gl::LevelIndex level, 467 GLuint layerIndex, 468 GLuint layerCount); 469 angle::Result getLevelLayerImageView(vk::Context *context, 470 gl::LevelIndex levelGL, 471 size_t layer, 472 const vk::ImageView **imageViewOut); 473 474 // Flush image's staged updates for all levels and layers. 475 angle::Result flushImageStagedUpdates(ContextVk *contextVk); 476 477 // For various reasons, the underlying image may need to be respecified. For example because 478 // base/max level changed, usage/create flags have changed, the format needs modification to 479 // become renderable, generate mipmap is adding levels, etc. This function is called by 480 // syncState and getAttachmentRenderTarget. The latter calls this function to be able to sync 481 // the texture's image while an attached framebuffer is being synced. Note that we currently 482 // sync framebuffers before textures so that the deferred clear optimization works. 483 angle::Result respecifyImageStorageIfNecessary(ContextVk *contextVk, gl::Command source); 484 485 const gl::InternalFormat &getImplementationSizedFormat(const gl::Context *context) const; 486 const vk::Format &getBaseLevelFormat(RendererVk *renderer) const; 487 // Queues a flush of any modified image attributes. The image will be reallocated with its new 488 // attributes at the next opportunity. 489 angle::Result respecifyImageStorage(ContextVk *contextVk); 490 491 // Update base and max levels, and re-create image if needed. 492 angle::Result maybeUpdateBaseMaxLevels(ContextVk *contextVk, 493 TextureUpdateResult *changeResultOut); 494 495 bool isFastUnpackPossible(const vk::Format &vkFormat, size_t offset) const; 496 497 bool shouldUpdateBeStaged(gl::LevelIndex textureLevelIndexGL, 498 angle::FormatID dstFormatID) const; 499 500 // We monitor the staging buffer and set dirty bits if the staging buffer changes. Note that we 501 // support changes in the staging buffer even outside the TextureVk class. 502 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 503 getTilingMode()504 ANGLE_INLINE VkImageTiling getTilingMode() 505 { 506 return (mImage->valid()) ? mImage->getTilingMode() : VK_IMAGE_TILING_OPTIMAL; 507 } 508 509 angle::Result refreshImageViews(ContextVk *contextVk); 510 bool shouldDecodeSRGB(vk::Context *context, GLenum srgbDecode, bool texelFetchStaticUse) const; 511 void initImageUsageFlags(ContextVk *contextVk, angle::FormatID actualFormatID); 512 void handleImmutableSamplerTransition(const vk::ImageHelper *previousImage, 513 const vk::ImageHelper *nextImage); 514 getRequiredImageAccess()515 vk::ImageAccess getRequiredImageAccess() const { return mRequiredImageAccess; } 516 bool imageHasActualImageFormat(angle::FormatID actualFormatID) const; 517 518 void stageSelfAsSubresourceUpdates(ContextVk *contextVk); 519 520 vk::ImageOrBufferViewSubresourceSerial getImageViewSubresourceSerialImpl( 521 GLenum srgbDecode) const; 522 523 void updateCachedImageViewSerials(); 524 525 bool mOwnsImage; 526 bool mRequiresMutableStorage; 527 vk::ImageAccess mRequiredImageAccess; 528 bool mImmutableSamplerDirty; 529 530 // Only valid if this texture is an "EGLImage target" and the associated EGL Image was 531 // originally sourced from an OpenGL texture. Such EGL Images can be a slice of the underlying 532 // resource. The layer and level offsets are used to track the location of the slice. 533 gl::TextureType mEGLImageNativeType; 534 uint32_t mEGLImageLayerOffset; 535 uint32_t mEGLImageLevelOffset; 536 537 // If multisampled rendering to texture, an intermediate multisampled image is created for use 538 // as renderpass color attachment. An array of images and image views are used based on the 539 // number of samples used with multisampled rendering to texture. Index 0 corresponds to the 540 // non-multisampled-render-to-texture usage of the texture. 541 542 // - index 0: Unused. See description of |mImage|. 543 // - index N: intermediate multisampled image used for multisampled rendering to texture with 544 // 1 << N samples 545 gl::RenderToTextureImageMap<vk::ImageHelper> mMultisampledImages; 546 547 // |ImageViewHelper| contains all the current views for the Texture. The views are always owned 548 // by the Texture and are not shared like |mImage|. They also have different lifetimes and can 549 // be reallocated independently of |mImage| on state changes. 550 // 551 // - index 0: views for the texture's image (regardless of |mOwnsImage|). 552 // - index N: views for mMultisampledImages[N] 553 gl::RenderToTextureImageMap<vk::ImageViewHelper> mMultisampledImageViews; 554 555 // Texture buffers create texel buffer views instead. |BufferViewHelper| contains the views 556 // corresponding to the attached buffer range. 557 vk::BufferViewHelper mBufferViews; 558 559 // Render targets stored as array of vector of vectors 560 // 561 // - First dimension: index N contains render targets with views from mMultisampledImageViews[N] 562 // - Second dimension: level 563 // - Third dimension: layer 564 gl::RenderToTextureImageMap<std::vector<RenderTargetVector>> mSingleLayerRenderTargets; 565 // Multi-layer render targets stored as a hash map. This is used for layered attachments 566 // which covers the entire layer (glFramebufferTextureLayer) or multiview attachments which 567 // cover a range of layers (glFramebufferTextureMultiviewOVR). 568 angle::HashMap<vk::ImageSubresourceRange, std::unique_ptr<RenderTargetVk>> 569 mMultiLayerRenderTargets; 570 571 // |mImage| wraps a VkImage and VkDeviceMemory that represents the gl::Texture. |mOwnsImage| 572 // indicates that |TextureVk| owns the image. Otherwise it is a weak pointer shared with another 573 // class. Due to this sharing, for example through EGL images, the image must always be 574 // dynamically allocated as the texture can release ownership for example and it can be 575 // transferred to another |TextureVk|. 576 vk::ImageHelper *mImage; 577 578 // |mSampler| contains the relevant Vulkan sampler states representing the OpenGL Texture 579 // sampling states for the Texture. 580 vk::SamplerBinding mSampler; 581 582 // The created vkImage usage flag. 583 VkImageUsageFlags mImageUsageFlags; 584 585 // Additional image create flags 586 VkImageCreateFlags mImageCreateFlags; 587 588 // If an image level is incompatibly redefined, the image lives through the call that did this 589 // (i.e. set and copy levels), because the image may be used by the framebuffer in the very same 590 // call. As a result, updates to this redefined level are staged (in both the call that 591 // redefines it, and any future calls such as subimage updates). This bitset flags redefined 592 // levels so that their updates will be force-staged until image is recreated. 593 // 594 // In common cases with mipmapped textures, the base/max level would need adjusting as the 595 // texture is no longer mip-complete. However, if every level is redefined such that at the end 596 // the image becomes mip-complete again, no reinitialization of the image is done. This bitset 597 // is additionally used to ensure the image is recreated in the next syncState, if not already. 598 // 599 // Note: this bitmask is for gl::LevelIndex, not vk::LevelIndex 600 gl::TexLevelMask mRedefinedLevels; 601 602 angle::ObserverBinding mImageObserverBinding; 603 604 // Saved between updates. 605 gl::LevelIndex mCurrentBaseLevel; 606 gl::LevelIndex mCurrentMaxLevel; 607 608 // Cached subresource indexes. 609 vk::ImageOrBufferViewSubresourceSerial mCachedImageViewSubresourceSerialSRGBDecode; 610 vk::ImageOrBufferViewSubresourceSerial mCachedImageViewSubresourceSerialSkipDecode; 611 }; 612 613 } // namespace rx 614 615 #endif // LIBANGLE_RENDERER_VULKAN_TEXTUREVK_H_ 616