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