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