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