• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 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 // TextureMtl.h:
7 //    Defines the class interface for TextureMtl, implementing TextureImpl.
8 //
9 
10 #ifndef LIBANGLE_RENDERER_METAL_TEXTUREMTL_H_
11 #define LIBANGLE_RENDERER_METAL_TEXTUREMTL_H_
12 
13 #include <map>
14 
15 #include "common/PackedEnums.h"
16 #include "libANGLE/renderer/TextureImpl.h"
17 #include "libANGLE/renderer/metal/RenderTargetMtl.h"
18 #include "libANGLE/renderer/metal/mtl_command_buffer.h"
19 #include "libANGLE/renderer/metal/mtl_resources.h"
20 
21 namespace rx
22 {
23 
24 class TextureMtl : public TextureImpl
25 {
26   public:
27     TextureMtl(const gl::TextureState &state);
28     ~TextureMtl() override;
29     void onDestroy(const gl::Context *context) override;
30 
31     angle::Result setImage(const gl::Context *context,
32                            const gl::ImageIndex &index,
33                            GLenum internalFormat,
34                            const gl::Extents &size,
35                            GLenum format,
36                            GLenum type,
37                            const gl::PixelUnpackState &unpack,
38                            gl::Buffer *unpackBuffer,
39                            const uint8_t *pixels) override;
40     angle::Result setSubImage(const gl::Context *context,
41                               const gl::ImageIndex &index,
42                               const gl::Box &area,
43                               GLenum format,
44                               GLenum type,
45                               const gl::PixelUnpackState &unpack,
46                               gl::Buffer *unpackBuffer,
47                               const uint8_t *pixels) override;
48 
49     angle::Result setCompressedImage(const gl::Context *context,
50                                      const gl::ImageIndex &index,
51                                      GLenum internalFormat,
52                                      const gl::Extents &size,
53                                      const gl::PixelUnpackState &unpack,
54                                      size_t imageSize,
55                                      const uint8_t *pixels) override;
56     angle::Result setCompressedSubImage(const gl::Context *context,
57                                         const gl::ImageIndex &index,
58                                         const gl::Box &area,
59                                         GLenum format,
60                                         const gl::PixelUnpackState &unpack,
61                                         size_t imageSize,
62                                         const uint8_t *pixels) override;
63 
64     angle::Result copyImage(const gl::Context *context,
65                             const gl::ImageIndex &index,
66                             const gl::Rectangle &sourceArea,
67                             GLenum internalFormat,
68                             gl::Framebuffer *source) override;
69     angle::Result copySubImage(const gl::Context *context,
70                                const gl::ImageIndex &index,
71                                const gl::Offset &destOffset,
72                                const gl::Rectangle &sourceArea,
73                                gl::Framebuffer *source) override;
74 
75     angle::Result copyTexture(const gl::Context *context,
76                               const gl::ImageIndex &index,
77                               GLenum internalFormat,
78                               GLenum type,
79                               size_t sourceLevel,
80                               bool unpackFlipY,
81                               bool unpackPremultiplyAlpha,
82                               bool unpackUnmultiplyAlpha,
83                               const gl::Texture *source) override;
84     angle::Result copySubTexture(const gl::Context *context,
85                                  const gl::ImageIndex &index,
86                                  const gl::Offset &destOffset,
87                                  size_t sourceLevel,
88                                  const gl::Box &sourceBox,
89                                  bool unpackFlipY,
90                                  bool unpackPremultiplyAlpha,
91                                  bool unpackUnmultiplyAlpha,
92                                  const gl::Texture *source) override;
93 
94     angle::Result copyCompressedTexture(const gl::Context *context,
95                                         const gl::Texture *source) override;
96 
97     angle::Result setStorage(const gl::Context *context,
98                              gl::TextureType type,
99                              size_t levels,
100                              GLenum internalFormat,
101                              const gl::Extents &size) override;
102 
103     angle::Result setStorageExternalMemory(const gl::Context *context,
104                                            gl::TextureType type,
105                                            size_t levels,
106                                            GLenum internalFormat,
107                                            const gl::Extents &size,
108                                            gl::MemoryObject *memoryObject,
109                                            GLuint64 offset) override;
110 
111     angle::Result setEGLImageTarget(const gl::Context *context,
112                                     gl::TextureType type,
113                                     egl::Image *image) override;
114 
115     angle::Result setImageExternal(const gl::Context *context,
116                                    gl::TextureType type,
117                                    egl::Stream *stream,
118                                    const egl::Stream::GLTextureDescription &desc) override;
119 
120     angle::Result generateMipmap(const gl::Context *context) override;
121 
122     angle::Result setBaseLevel(const gl::Context *context, GLuint baseLevel) override;
123 
124     angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override;
125     angle::Result releaseTexImage(const gl::Context *context) override;
126 
127     angle::Result getAttachmentRenderTarget(const gl::Context *context,
128                                             GLenum binding,
129                                             const gl::ImageIndex &imageIndex,
130                                             GLsizei samples,
131                                             FramebufferAttachmentRenderTarget **rtOut) override;
132 
133     angle::Result syncState(const gl::Context *context,
134                             const gl::Texture::DirtyBits &dirtyBits) override;
135 
136     angle::Result setStorageMultisample(const gl::Context *context,
137                                         gl::TextureType type,
138                                         GLsizei samples,
139                                         GLint internalformat,
140                                         const gl::Extents &size,
141                                         bool fixedSampleLocations) override;
142 
143     angle::Result initializeContents(const gl::Context *context,
144                                      const gl::ImageIndex &imageIndex) override;
145 
146     // The texture's data is initially initialized and stored in an array
147     // of images through glTexImage*/glCopyTex* calls. During draw calls, the caller must make sure
148     // the actual texture is created by calling this method to transfer the stored images data
149     // to the actual texture.
150     angle::Result ensureTextureCreated(const gl::Context *context);
151 
152     angle::Result bindVertexShader(const gl::Context *context,
153                                    mtl::RenderCommandEncoder *cmdEncoder,
154                                    int textureSlotIndex,
155                                    int samplerSlotIndex);
156     angle::Result bindFragmentShader(const gl::Context *context,
157                                      mtl::RenderCommandEncoder *cmdEncoder,
158                                      int textureSlotIndex,
159                                      int samplerSlotIndex);
160 
getFormat()161     const mtl::Format &getFormat() const { return mFormat; }
162 
163   private:
164     void releaseTexture(bool releaseImages);
165     angle::Result ensureSamplerStateCreated(const gl::Context *context);
166     // Ensure image at given index is created:
167     angle::Result ensureImageCreated(const gl::Context *context, const gl::ImageIndex &index);
168     angle::Result checkForEmulatedChannels(const gl::Context *context,
169                                            const mtl::Format &mtlFormat,
170                                            const mtl::TextureRef &texture);
171 
172     // If levels = 0, this function will create full mipmaps texture.
173     angle::Result setStorageImpl(const gl::Context *context,
174                                  gl::TextureType type,
175                                  size_t levels,
176                                  const mtl::Format &mtlFormat,
177                                  const gl::Extents &size);
178 
179     angle::Result redefineImage(const gl::Context *context,
180                                 const gl::ImageIndex &index,
181                                 const mtl::Format &mtlFormat,
182                                 const gl::Extents &size);
183 
184     angle::Result setImageImpl(const gl::Context *context,
185                                const gl::ImageIndex &index,
186                                const gl::InternalFormat &formatInfo,
187                                const gl::Extents &size,
188                                GLenum type,
189                                const gl::PixelUnpackState &unpack,
190                                const uint8_t *pixels);
191     angle::Result setSubImageImpl(const gl::Context *context,
192                                   const gl::ImageIndex &index,
193                                   const gl::Box &area,
194                                   const gl::InternalFormat &formatInfo,
195                                   GLenum type,
196                                   const gl::PixelUnpackState &unpack,
197                                   const uint8_t *pixels);
198 
199     angle::Result copySubImageImpl(const gl::Context *context,
200                                    const gl::ImageIndex &index,
201                                    const gl::Offset &destOffset,
202                                    const gl::Rectangle &sourceArea,
203                                    const gl::InternalFormat &internalFormat,
204                                    gl::Framebuffer *source);
205     angle::Result copySubImageWithDraw(const gl::Context *context,
206                                        const gl::ImageIndex &index,
207                                        const gl::Offset &destOffset,
208                                        const gl::Rectangle &sourceArea,
209                                        const gl::InternalFormat &internalFormat,
210                                        gl::Framebuffer *source);
211     angle::Result copySubImageCPU(const gl::Context *context,
212                                   const gl::ImageIndex &index,
213                                   const gl::Offset &destOffset,
214                                   const gl::Rectangle &sourceArea,
215                                   const gl::InternalFormat &internalFormat,
216                                   gl::Framebuffer *source);
217 
218     // Convert pixels to suported format before uploading to texture
219     angle::Result convertAndSetSubImage(const gl::Context *context,
220                                         const gl::ImageIndex &index,
221                                         const MTLRegion &mtlArea,
222                                         const gl::InternalFormat &internalFormat,
223                                         const angle::Format &pixelsFormat,
224                                         size_t pixelsRowPitch,
225                                         const uint8_t *pixels);
226 
227     angle::Result generateMipmapCPU(const gl::Context *context);
228 
229     mtl::Format mFormat;
230     // The real texture used by Metal draw calls.
231     mtl::TextureRef mNativeTexture;
232     id<MTLSamplerState> mMetalSamplerState = nil;
233 
234     std::vector<RenderTargetMtl> mLayeredRenderTargets;
235     std::vector<mtl::TextureRef> mLayeredTextureViews;
236 
237     // Stored images array defined by glTexImage/glCopy*.
238     // Once the images array is complete, they will be transferred to real texture object.
239     std::map<int, gl::TexLevelArray<mtl::TextureRef>> mTexImages;
240 
241     bool mIsPow2 = false;
242 };
243 
244 }  // namespace rx
245 
246 #endif /* LIBANGLE_RENDERER_METAL_TEXTUREMTL_H_ */
247