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