• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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