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::Context *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::Context *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::Context *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::Context *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 angle::Result performImageQueueTransferIfNecessary(ContextVk *contextVk); 569 570 // For various reasons, the underlying image may need to be respecified. For example because 571 // base/max level changed, usage/create flags have changed, the format needs modification to 572 // become renderable, generate mipmap is adding levels, etc. This function is called by 573 // syncState and getAttachmentRenderTarget. The latter calls this function to be able to sync 574 // the texture's image while an attached framebuffer is being synced. Note that we currently 575 // sync framebuffers before textures so that the deferred clear optimization works. 576 angle::Result respecifyImageStorageIfNecessary(ContextVk *contextVk, gl::Command source); 577 578 const gl::InternalFormat &getImplementationSizedFormat(const gl::Context *context) const; 579 const vk::Format &getBaseLevelFormat(vk::Renderer *renderer) const; 580 // Queues a flush of any modified image attributes. The image will be reallocated with its new 581 // attributes at the next opportunity. 582 angle::Result respecifyImageStorage(ContextVk *contextVk); 583 584 // Update base and max levels, and re-create image if needed. 585 angle::Result maybeUpdateBaseMaxLevels(ContextVk *contextVk, 586 TextureUpdateResult *changeResultOut); 587 588 bool isFastUnpackPossible(const vk::Format &vkFormat, 589 size_t offset, 590 const vk::Format &bufferVkFormat) const; 591 592 bool updateMustBeStaged(gl::LevelIndex textureLevelIndexGL, angle::FormatID dstFormatID) const; 593 bool updateMustBeFlushed(gl::LevelIndex textureLevelIndexGL, angle::FormatID dstFormatID) const; shouldUpdateBeFlushed(gl::LevelIndex textureLevelIndexGL,angle::FormatID dstFormatID)594 bool shouldUpdateBeFlushed(gl::LevelIndex textureLevelIndexGL, 595 angle::FormatID dstFormatID) const 596 { 597 return updateMustBeFlushed(textureLevelIndexGL, dstFormatID) || 598 !updateMustBeStaged(textureLevelIndexGL, dstFormatID); 599 } 600 601 // We monitor the staging buffer and set dirty bits if the staging buffer changes. Note that we 602 // support changes in the staging buffer even outside the TextureVk class. 603 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 604 getTilingMode()605 ANGLE_INLINE VkImageTiling getTilingMode() 606 { 607 return mImage != nullptr && mImage->valid() ? mImage->getTilingMode() 608 : VK_IMAGE_TILING_OPTIMAL; 609 } 610 611 angle::Result ensureMutable(ContextVk *contextVk); 612 angle::Result refreshImageViews(ContextVk *contextVk); 613 void initImageUsageFlags(ContextVk *contextVk, angle::FormatID actualFormatID); 614 void handleImmutableSamplerTransition(const vk::ImageHelper *previousImage, 615 const vk::ImageHelper *nextImage); 616 getRequiredImageAccess()617 vk::ImageAccess getRequiredImageAccess() const { return mRequiredImageAccess; } 618 619 void stageSelfAsSubresourceUpdates(ContextVk *contextVk); 620 621 vk::ImageOrBufferViewSubresourceSerial getImageViewSubresourceSerialImpl( 622 vk::ImageViewColorspace colorspace) const; 623 624 void updateCachedImageViewSerials(); 625 626 angle::Result updateTextureLabel(ContextVk *contextVk); 627 628 vk::BufferHelper *getRGBAConversionBufferHelper(vk::Renderer *renderer, 629 angle::FormatID formatID) const; 630 angle::Result convertBufferToRGBA(ContextVk *contextVk, size_t &conversionBufferSize); 631 bool isCompressedFormatEmulated(const gl::Context *context, 632 const gl::TextureTarget target, 633 GLint level); 634 635 angle::Result setStorageImpl(ContextVk *contextVk, 636 gl::TextureType type, 637 const vk::Format &format); 638 639 GLint getFormatSupportedCompressionRatesImpl(vk::Renderer *renderer, 640 const vk::Format &format, 641 GLsizei bufSize, 642 GLint *rates); 643 644 bool mOwnsImage; 645 // Generated from ImageVk if EGLImage target, or from throw-away generator if Surface target. 646 UniqueSerial mImageSiblingSerial; 647 648 bool mRequiresMutableStorage; 649 vk::ImageAccess mRequiredImageAccess; 650 bool mImmutableSamplerDirty; 651 652 // Only valid if this texture is an "EGLImage target" and the associated EGL Image was 653 // originally sourced from an OpenGL texture. Such EGL Images can be a slice of the underlying 654 // resource. The layer and level offsets are used to track the location of the slice. 655 gl::TextureType mEGLImageNativeType; 656 uint32_t mEGLImageLayerOffset; 657 uint32_t mEGLImageLevelOffset; 658 659 // If multisampled rendering to texture, an intermediate multisampled image is created for use 660 // as renderpass color attachment. A map of an array of images and image views are used where - 661 // 662 // The map is keyed based on the number of samples used with multisampled rendering to texture. 663 // Index 0 corresponds to the non-multisampled-render-to-texture usage of the texture. 664 // - index 0: Unused. See description of |mImage|. 665 // - index N: intermediate multisampled image used for multisampled rendering to texture with 666 // 1 << N samples 667 // 668 // Each element in the array corresponds to a mip-level 669 // 670 // - mMultisampledImages[N][M]: intermediate multisampled image with 1 << N samples 671 // for level index M 672 using MultiSampleImages = gl::RenderToTextureImageMap<gl::TexLevelArray<vk::ImageHelper>>; 673 std::unique_ptr<MultiSampleImages> mMultisampledImages; 674 675 // If multisampled rendering to texture, contains views for mMultisampledImages. 676 // 677 // - index 0: Unused. See description of |mImageView|. 678 // - mMultisampledImageViews[N][M]: views for mMultisampledImages[N][M] 679 using MultiSampleImageViews = 680 gl::RenderToTextureImageMap<gl::TexLevelArray<vk::ImageViewHelper>>; 681 std::unique_ptr<MultiSampleImageViews> mMultisampledImageViews; 682 683 // Texture buffers create texel buffer views instead. |BufferViewHelper| contains the views 684 // corresponding to the attached buffer range. 685 vk::BufferViewHelper mBufferViews; 686 687 // Render targets stored as array of vector of vectors 688 // 689 // - First dimension: index N contains render targets with views from mMultisampledImageViews[N] 690 // - Second dimension: level M contains render targets with views from 691 // mMultisampledImageViews[N][M] 692 // - Third dimension: layer 693 gl::RenderToTextureImageMap<std::vector<RenderTargetVector>> mSingleLayerRenderTargets; 694 // Multi-layer render targets stored as a hash map. This is used for layered attachments 695 // which covers the entire layer (glFramebufferTextureLayer) or multiview attachments which 696 // cover a range of layers (glFramebufferTextureMultiviewOVR). 697 angle::HashMap<vk::ImageSubresourceRange, std::unique_ptr<RenderTargetVk>> 698 mMultiLayerRenderTargets; 699 700 // |mImage| wraps a VkImage and VkDeviceMemory that represents the gl::Texture. |mOwnsImage| 701 // indicates that |TextureVk| owns the image. Otherwise it is a weak pointer shared with another 702 // class. Due to this sharing, for example through EGL images, the image must always be 703 // dynamically allocated as the texture can release ownership for example and it can be 704 // transferred to another |TextureVk|. 705 vk::ImageHelper *mImage; 706 // The view is always owned by the Texture and is not shared like |mImage|. It also has 707 // different lifetimes and can be reallocated independently of |mImage| on state changes. 708 vk::ImageViewHelper mImageView; 709 710 // |mSampler| contains the relevant Vulkan sampler states representing the OpenGL Texture 711 // sampling states for the Texture. 712 vk::SharedSamplerPtr mSampler; 713 // |mY2YSampler| contains a version of mSampler that is meant for use with 714 // __samplerExternal2DY2YEXT (i.e., skipping conversion of YUV to RGB). 715 vk::SharedSamplerPtr mY2YSampler; 716 717 // The created vkImage usage flag. 718 VkImageUsageFlags mImageUsageFlags; 719 720 // Additional image create flags 721 VkImageCreateFlags mImageCreateFlags; 722 723 // If an image level is incompatibly redefined, the image lives through the call that did this 724 // (i.e. set and copy levels), because the image may be used by the framebuffer in the very same 725 // call. As a result, updates to this redefined level are staged (in both the call that 726 // redefines it, and any future calls such as subimage updates). This array flags redefined 727 // levels so that their updates will be force-staged until image is recreated. Each member of 728 // the array is a bitmask per level, and it's an array of cube faces because GL allows 729 // redefining each cube map face separately. For other texture types, only index 0 is 730 // meaningful as all array levels are redefined simultaneously. 731 // 732 // In common cases with mipmapped textures, the base/max level would need adjusting as the 733 // texture is no longer mip-complete. However, if every level is redefined such that at the end 734 // the image becomes mip-complete again, no reinitialization of the image is done. This array 735 // is additionally used to ensure the image is recreated in the next syncState, if not already. 736 // 737 // Note: the elements of this array are bitmasks indexed by gl::LevelIndex, not vk::LevelIndex 738 gl::CubeFaceArray<gl::TexLevelMask> mRedefinedLevels; 739 740 angle::ObserverBinding mImageObserverBinding; 741 742 // Saved between updates. 743 gl::LevelIndex mCurrentBaseLevel; 744 gl::LevelIndex mCurrentMaxLevel; 745 746 // Cached subresource indexes. 747 vk::ImageOrBufferViewSubresourceSerial mCachedImageViewSubresourceSerialSRGBDecode; 748 vk::ImageOrBufferViewSubresourceSerial mCachedImageViewSubresourceSerialSkipDecode; 749 750 // Manages the texture descriptor set cache that created with this texture 751 vk::DescriptorSetCacheManager mDescriptorSetCacheManager; 752 }; 753 754 } // namespace rx 755 756 #endif // LIBANGLE_RENDERER_VULKAN_TEXTUREVK_H_ 757