• 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/CommandGraph.h"
15 #include "libANGLE/renderer/vulkan/RenderTargetVk.h"
16 #include "libANGLE/renderer/vulkan/SamplerVk.h"
17 #include "libANGLE/renderer/vulkan/vk_helpers.h"
18 
19 namespace rx
20 {
21 
22 class TextureVk : public TextureImpl
23 {
24   public:
25     TextureVk(const gl::TextureState &state, RendererVk *renderer);
26     ~TextureVk() override;
27     void onDestroy(const gl::Context *context) override;
28 
29     angle::Result setImage(const gl::Context *context,
30                            const gl::ImageIndex &index,
31                            GLenum internalFormat,
32                            const gl::Extents &size,
33                            GLenum format,
34                            GLenum type,
35                            const gl::PixelUnpackState &unpack,
36                            const uint8_t *pixels) override;
37     angle::Result setSubImage(const gl::Context *context,
38                               const gl::ImageIndex &index,
39                               const gl::Box &area,
40                               GLenum format,
41                               GLenum type,
42                               const gl::PixelUnpackState &unpack,
43                               gl::Buffer *unpackBuffer,
44                               const uint8_t *pixels) override;
45 
46     angle::Result setCompressedImage(const gl::Context *context,
47                                      const gl::ImageIndex &index,
48                                      GLenum internalFormat,
49                                      const gl::Extents &size,
50                                      const gl::PixelUnpackState &unpack,
51                                      size_t imageSize,
52                                      const uint8_t *pixels) override;
53     angle::Result setCompressedSubImage(const gl::Context *context,
54                                         const gl::ImageIndex &index,
55                                         const gl::Box &area,
56                                         GLenum format,
57                                         const gl::PixelUnpackState &unpack,
58                                         size_t imageSize,
59                                         const uint8_t *pixels) override;
60 
61     angle::Result copyImage(const gl::Context *context,
62                             const gl::ImageIndex &index,
63                             const gl::Rectangle &sourceArea,
64                             GLenum internalFormat,
65                             gl::Framebuffer *source) override;
66     angle::Result copySubImage(const gl::Context *context,
67                                const gl::ImageIndex &index,
68                                const gl::Offset &destOffset,
69                                const gl::Rectangle &sourceArea,
70                                gl::Framebuffer *source) override;
71 
72     angle::Result copyTexture(const gl::Context *context,
73                               const gl::ImageIndex &index,
74                               GLenum internalFormat,
75                               GLenum type,
76                               size_t sourceLevel,
77                               bool unpackFlipY,
78                               bool unpackPremultiplyAlpha,
79                               bool unpackUnmultiplyAlpha,
80                               const gl::Texture *source) override;
81     angle::Result copySubTexture(const gl::Context *context,
82                                  const gl::ImageIndex &index,
83                                  const gl::Offset &destOffset,
84                                  size_t sourceLevel,
85                                  const gl::Box &sourceBox,
86                                  bool unpackFlipY,
87                                  bool unpackPremultiplyAlpha,
88                                  bool unpackUnmultiplyAlpha,
89                                  const gl::Texture *source) override;
90 
91     angle::Result copyCompressedTexture(const gl::Context *context,
92                                         const gl::Texture *source) override;
93 
94     angle::Result setStorage(const gl::Context *context,
95                              gl::TextureType type,
96                              size_t levels,
97                              GLenum internalFormat,
98                              const gl::Extents &size) override;
99 
100     angle::Result setStorageExternalMemory(const gl::Context *context,
101                                            gl::TextureType type,
102                                            size_t levels,
103                                            GLenum internalFormat,
104                                            const gl::Extents &size,
105                                            gl::MemoryObject *memoryObject,
106                                            GLuint64 offset) override;
107 
108     angle::Result setEGLImageTarget(const gl::Context *context,
109                                     gl::TextureType type,
110                                     egl::Image *image) override;
111 
112     angle::Result setImageExternal(const gl::Context *context,
113                                    gl::TextureType type,
114                                    egl::Stream *stream,
115                                    const egl::Stream::GLTextureDescription &desc) override;
116 
117     angle::Result generateMipmap(const gl::Context *context) override;
118 
119     angle::Result setBaseLevel(const gl::Context *context, GLuint baseLevel) override;
120 
121     angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override;
122     angle::Result releaseTexImage(const gl::Context *context) override;
123 
124     angle::Result getAttachmentRenderTarget(const gl::Context *context,
125                                             GLenum binding,
126                                             const gl::ImageIndex &imageIndex,
127                                             FramebufferAttachmentRenderTarget **rtOut) override;
128 
129     angle::Result syncState(const gl::Context *context,
130                             const gl::Texture::DirtyBits &dirtyBits) override;
131 
132     angle::Result setStorageMultisample(const gl::Context *context,
133                                         gl::TextureType type,
134                                         GLsizei samples,
135                                         GLint internalformat,
136                                         const gl::Extents &size,
137                                         bool fixedSampleLocations) override;
138 
139     angle::Result initializeContents(const gl::Context *context,
140                                      const gl::ImageIndex &imageIndex) override;
141 
getImage()142     const vk::ImageHelper &getImage() const
143     {
144         ASSERT(mImage && mImage->valid());
145         return *mImage;
146     }
147 
getImage()148     vk::ImageHelper &getImage()
149     {
150         ASSERT(mImage && mImage->valid());
151         return *mImage;
152     }
153 
154     void releaseOwnershipOfImage(const gl::Context *context);
155 
156     const vk::ImageView &getReadImageView() const;
157     // A special view for cube maps as a 2D array, used with shaders that do texelFetch() and for
158     // seamful cube map emulation.
159     const vk::ImageView &getFetchImageView() const;
160     angle::Result getLayerLevelDrawImageView(vk::Context *context,
161                                              size_t layer,
162                                              size_t level,
163                                              vk::ImageView **imageViewOut);
164     const vk::Sampler &getSampler() const;
165 
166     angle::Result ensureImageInitialized(ContextVk *contextVk);
167 
getSerial()168     Serial getSerial() const { return mSerial; }
169 
overrideStagingBufferSizeForTesting(size_t initialSizeForTesting)170     void overrideStagingBufferSizeForTesting(size_t initialSizeForTesting)
171     {
172         mStagingBufferInitialSize = initialSizeForTesting;
173     }
174 
175   private:
176     struct TextureVkViews final : angle::NonCopyable
177     {
178         TextureVkViews();
179         ~TextureVkViews();
180 
181         void release(ContextVk *contextVk, Serial currentSerial);
182         vk::ImageView mDrawBaseLevelImageView;
183         vk::ImageView mReadBaseLevelImageView;
184         vk::ImageView mReadMipmapImageView;
185         vk::ImageView mFetchBaseLevelImageView;
186         vk::ImageView mFetchMipmapImageView;
187     };
188 
189     // Transform an image index from the frontend into one that can be used on the backing
190     // ImageHelper, taking into account mipmap or cube face offsets
191     gl::ImageIndex getNativeImageIndex(const gl::ImageIndex &inputImageIndex) const;
192     uint32_t getNativeImageLevel(uint32_t frontendLevel) const;
193     uint32_t getNativeImageLayer(uint32_t frontendLayer) const;
194 
195     void releaseAndDeleteImage(ContextVk *contextVk);
196     angle::Result ensureImageAllocated(ContextVk *contextVk, const vk::Format &format);
197     void setImageHelper(ContextVk *contextVk,
198                         vk::ImageHelper *imageHelper,
199                         gl::TextureType imageType,
200                         const vk::Format &format,
201                         uint32_t imageLevelOffset,
202                         uint32_t imageLayerOffset,
203                         bool selfOwned);
204     void updateImageHelper(ContextVk *context, const vk::Format &internalFormat);
205 
206     angle::Result redefineImage(const gl::Context *context,
207                                 const gl::ImageIndex &index,
208                                 const vk::Format &format,
209                                 const gl::Extents &size);
210 
211     angle::Result setImageImpl(const gl::Context *context,
212                                const gl::ImageIndex &index,
213                                const gl::InternalFormat &formatInfo,
214                                const gl::Extents &size,
215                                GLenum type,
216                                const gl::PixelUnpackState &unpack,
217                                const uint8_t *pixels);
218     angle::Result setSubImageImpl(const gl::Context *context,
219                                   const gl::ImageIndex &index,
220                                   const gl::Box &area,
221                                   const gl::InternalFormat &formatInfo,
222                                   GLenum type,
223                                   const gl::PixelUnpackState &unpack,
224                                   const uint8_t *pixels,
225                                   const vk::Format &vkFormat);
226 
227     angle::Result copyImageDataToBuffer(ContextVk *contextVk,
228                                         size_t sourceLevel,
229                                         uint32_t layerCount,
230                                         const gl::Rectangle &sourceArea,
231                                         uint8_t **outDataPtr);
232 
233     angle::Result generateMipmapsWithCPU(const gl::Context *context);
234 
235     angle::Result generateMipmapLevelsWithCPU(ContextVk *contextVk,
236                                               const angle::Format &sourceFormat,
237                                               GLuint layer,
238                                               GLuint firstMipLevel,
239                                               GLuint maxMipLevel,
240                                               size_t sourceWidth,
241                                               size_t sourceHeight,
242                                               size_t sourceRowPitch,
243                                               uint8_t *sourceData);
244 
245     angle::Result copySubImageImpl(const gl::Context *context,
246                                    const gl::ImageIndex &index,
247                                    const gl::Offset &destOffset,
248                                    const gl::Rectangle &sourceArea,
249                                    const gl::InternalFormat &internalFormat,
250                                    gl::Framebuffer *source);
251 
252     angle::Result copySubTextureImpl(ContextVk *contextVk,
253                                      const gl::ImageIndex &index,
254                                      const gl::Offset &destOffset,
255                                      const gl::InternalFormat &destFormat,
256                                      size_t sourceLevel,
257                                      const gl::Rectangle &sourceArea,
258                                      bool unpackFlipY,
259                                      bool unpackPremultiplyAlpha,
260                                      bool unpackUnmultiplyAlpha,
261                                      TextureVk *source);
262 
263     angle::Result copySubImageImplWithTransfer(ContextVk *contextVk,
264                                                const gl::ImageIndex &index,
265                                                const gl::Offset &destOffset,
266                                                const vk::Format &destFormat,
267                                                size_t sourceLevel,
268                                                size_t sourceLayer,
269                                                const gl::Rectangle &sourceArea,
270                                                vk::ImageHelper *srcImage);
271 
272     angle::Result copySubImageImplWithDraw(ContextVk *contextVk,
273                                            const gl::ImageIndex &index,
274                                            const gl::Offset &destOffset,
275                                            const vk::Format &destFormat,
276                                            size_t sourceLevel,
277                                            const gl::Rectangle &sourceArea,
278                                            bool isSrcFlipY,
279                                            bool unpackFlipY,
280                                            bool unpackPremultiplyAlpha,
281                                            bool unpackUnmultiplyAlpha,
282                                            vk::ImageHelper *srcImage,
283                                            const vk::ImageView *srcView);
284 
285     angle::Result initImage(ContextVk *contextVk,
286                             const vk::Format &format,
287                             const gl::Extents &extents,
288                             const uint32_t levelCount,
289                             vk::CommandBuffer *commandBuffer);
290     void releaseImage(ContextVk *context);
291     void releaseImageViews(ContextVk *contextVk);
292     void releaseStagingBuffer(ContextVk *context);
293     uint32_t getLevelCount() const;
294     angle::Result initImageViews(ContextVk *contextVk,
295                                  const vk::Format &format,
296                                  uint32_t levelCount,
297                                  uint32_t layerCount);
298     angle::Result init3DRenderTargets(ContextVk *contextVk);
299     angle::Result initImageViewImpl(ContextVk *contextVk,
300                                     const vk::Format &format,
301                                     uint32_t levelCount,
302                                     uint32_t layerCount,
303                                     TextureVkViews *views,
304                                     VkImageAspectFlags aspectFlags,
305                                     gl::SwizzleState mappedSwizzle);
306     angle::Result initCubeMapRenderTargets(ContextVk *contextVk);
307 
308     angle::Result ensureImageInitializedImpl(ContextVk *contextVk,
309                                              const gl::Extents &baseLevelExtents,
310                                              uint32_t levelCount,
311                                              const vk::Format &format);
312 
onStagingBufferChange()313     void onStagingBufferChange() { onStateChange(angle::SubjectMessage::SubjectChanged); }
314 
315     const TextureVkViews *getTextureViews() const;
316 
317     bool mOwnsImage;
318 
319     gl::TextureType mImageNativeType;
320 
321     // The layer offset to apply when converting from a frontend texture layer to a texture layer in
322     // mImage. Used when this texture sources a cube map face or 3D texture layer from an EGL image.
323     uint32_t mImageLayerOffset;
324 
325     // The level offset to apply when converting from a frontend texture level to texture level in
326     // mImage.
327     uint32_t mImageLevelOffset;
328 
329     vk::ImageHelper *mImage;
330 
331     TextureVkViews mDefaultViews;
332     TextureVkViews mStencilViews;
333     std::vector<std::vector<vk::ImageView>> mLayerLevelDrawImageViews;
334     vk::Sampler mSampler;
335 
336     RenderTargetVk mRenderTarget;
337     std::vector<vk::ImageView> mLayerFetchImageView;
338     std::vector<RenderTargetVk> m3DRenderTargets;
339     std::vector<RenderTargetVk> mCubeMapRenderTargets;
340 
341     // The serial is used for cache indexing.
342     Serial mSerial;
343 
344     // Overridden in some tests.
345     size_t mStagingBufferInitialSize;
346 };
347 
348 }  // namespace rx
349 
350 #endif  // LIBANGLE_RENDERER_VULKAN_TEXTUREVK_H_
351