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