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