• 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 // mtl_utils.h:
7 //    Declares utilities functions that create Metal shaders, convert from angle enums
8 //    to Metal enums and so on.
9 //
10 
11 #ifndef LIBANGLE_RENDERER_METAL_MTL_UTILS_H_
12 #define LIBANGLE_RENDERER_METAL_MTL_UTILS_H_
13 
14 #import <Metal/Metal.h>
15 
16 #include "angle_gl.h"
17 #include "common/PackedEnums.h"
18 #include "libANGLE/Context.h"
19 #include "libANGLE/Texture.h"
20 #include "libANGLE/renderer/metal/mtl_format_utils.h"
21 #include "libANGLE/renderer/metal/mtl_resources.h"
22 #include "libANGLE/renderer/metal/mtl_state_cache.h"
23 
24 namespace rx
25 {
26 
27 class ContextMtl;
28 
29 void StartFrameCapture(id<MTLDevice> metalDevice, id<MTLCommandQueue> metalCmdQueue);
30 void StartFrameCapture(ContextMtl *context);
31 void StopFrameCapture();
32 
33 namespace mtl
34 {
35 
36 enum class StagingPurpose
37 {
38     Initialization,
39     Upload
40 };
41 
42 bool PreferStagedTextureUploads(const gl::Context *context,
43                                 const TextureRef &texture,
44                                 const Format &textureObjFormat,
45                                 const StagingPurpose purpose);
46 
47 // Initialize texture content to black.
48 angle::Result InitializeTextureContents(const gl::Context *context,
49                                         const TextureRef &texture,
50                                         const Format &textureObjFormat,
51                                         const ImageNativeIndex &index);
52 // Same as above but using GPU clear operation instead of CPU.forma
53 // - channelsToInit parameter controls which channels will get their content initialized.
54 angle::Result InitializeTextureContentsGPU(const gl::Context *context,
55                                            const TextureRef &texture,
56                                            const Format &textureObjFormat,
57                                            const ImageNativeIndex &index,
58                                            MTLColorWriteMask channelsToInit);
59 
60 // Same as above but for a depth/stencil texture.
61 angle::Result InitializeDepthStencilTextureContentsGPU(const gl::Context *context,
62                                                        const TextureRef &texture,
63                                                        const Format &textureObjFormat,
64                                                        const ImageNativeIndex &index);
65 
66 // Unified texture's per slice/depth texel reading function
67 angle::Result ReadTexturePerSliceBytes(const gl::Context *context,
68                                        const TextureRef &texture,
69                                        size_t bytesPerRow,
70                                        const gl::Rectangle &fromRegion,
71                                        const MipmapNativeLevel &mipLevel,
72                                        uint32_t sliceOrDepth,
73                                        uint8_t *dataOut);
74 
75 angle::Result ReadTexturePerSliceBytesToBuffer(const gl::Context *context,
76                                                const TextureRef &texture,
77                                                size_t bytesPerRow,
78                                                const gl::Rectangle &fromRegion,
79                                                const MipmapNativeLevel &mipLevel,
80                                                uint32_t sliceOrDepth,
81                                                uint32_t dstOffset,
82                                                const BufferRef &dstBuffer);
83 
84 MTLViewport GetViewport(const gl::Rectangle &rect, double znear = 0, double zfar = 1);
85 MTLViewport GetViewportFlipY(const gl::Rectangle &rect,
86                              NSUInteger screenHeight,
87                              double znear = 0,
88                              double zfar  = 1);
89 MTLViewport GetViewport(const gl::Rectangle &rect,
90                         NSUInteger screenHeight,
91                         bool flipY,
92                         double znear = 0,
93                         double zfar  = 1);
94 MTLScissorRect GetScissorRect(const gl::Rectangle &rect,
95                               NSUInteger screenHeight = 0,
96                               bool flipY              = false);
97 
98 uint32_t GetDeviceVendorId(id<MTLDevice> metalDevice);
99 
100 AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(
101     const mtl::ContextDevice &metalDevice,
102     const std::string &source,
103     const std::map<std::string, std::string> &substitutionDictionary,
104     bool disableFastMath,
105     bool usesInvariance,
106     AutoObjCPtr<NSError *> *error);
107 
108 AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(const mtl::ContextDevice &metalDevice,
109                                                 const std::string &source,
110                                                 AutoObjCPtr<NSError *> *error);
111 
112 AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(
113     const mtl::ContextDevice &metalDevice,
114     const char *source,
115     size_t sourceLen,
116     const std::map<std::string, std::string> &substitutionDictionary,
117     bool disableFastMath,
118     bool usesInvariance,
119     AutoObjCPtr<NSError *> *error);
120 
121 AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(id<MTLDevice> metalDevice,
122                                                 const char *source,
123                                                 size_t sourceLen,
124                                                 AutoObjCPtr<NSError *> *error);
125 
126 AutoObjCPtr<id<MTLLibrary>> CreateShaderLibraryFromBinary(id<MTLDevice> metalDevice,
127                                                           const uint8_t *binarySource,
128                                                           size_t binarySourceLen,
129                                                           AutoObjCPtr<NSError *> *error);
130 
131 // Compiles a shader library into a metallib file, returning the path to it.
132 std::string CompileShaderLibraryToFile(const std::string &source,
133                                        const std::map<std::string, std::string> &macros,
134                                        bool disableFastMath,
135                                        bool usesInvariance);
136 
137 bool SupportsAppleGPUFamily(id<MTLDevice> device, uint8_t appleFamily);
138 
139 bool SupportsMacGPUFamily(id<MTLDevice> device, uint8_t macFamily);
140 
141 // Need to define invalid enum value since Metal doesn't define it
142 constexpr MTLTextureType MTLTextureTypeInvalid = static_cast<MTLTextureType>(NSUIntegerMax);
143 static_assert(sizeof(MTLTextureType) == sizeof(NSUInteger),
144               "MTLTextureType is supposed to be based on NSUInteger");
145 
146 constexpr MTLPrimitiveType MTLPrimitiveTypeInvalid = static_cast<MTLPrimitiveType>(NSUIntegerMax);
147 static_assert(sizeof(MTLPrimitiveType) == sizeof(NSUInteger),
148               "MTLPrimitiveType is supposed to be based on NSUInteger");
149 
150 constexpr MTLIndexType MTLIndexTypeInvalid = static_cast<MTLIndexType>(NSUIntegerMax);
151 static_assert(sizeof(MTLIndexType) == sizeof(NSUInteger),
152               "MTLIndexType is supposed to be based on NSUInteger");
153 
154 MTLTextureType GetTextureType(gl::TextureType glType);
155 
156 MTLSamplerMinMagFilter GetFilter(GLenum filter);
157 MTLSamplerMipFilter GetMipmapFilter(GLenum filter);
158 MTLSamplerAddressMode GetSamplerAddressMode(GLenum wrap);
159 
160 MTLBlendFactor GetBlendFactor(gl::BlendFactorType factor);
161 MTLBlendOperation GetBlendOp(gl::BlendEquationType op);
162 
163 MTLCompareFunction GetCompareFunc(GLenum func);
164 MTLStencilOperation GetStencilOp(GLenum op);
165 
166 MTLWinding GetFrontfaceWinding(GLenum frontFaceMode, bool invert);
167 
168 PrimitiveTopologyClass GetPrimitiveTopologyClass(gl::PrimitiveMode mode);
169 MTLPrimitiveType GetPrimitiveType(gl::PrimitiveMode mode);
170 MTLIndexType GetIndexType(gl::DrawElementsType type);
171 
172 #if ANGLE_MTL_SWIZZLE_AVAILABLE
173 MTLTextureSwizzle GetTextureSwizzle(GLenum swizzle);
174 #endif
175 
176 // Get color write mask for a specified format. Some formats such as RGB565 doesn't have alpha
177 // channel but is emulated by a RGBA8 format, we need to disable alpha write for this format.
178 // - emulatedChannelsOut: if the format is emulated, this pointer will store a true value.
179 MTLColorWriteMask GetEmulatedColorWriteMask(const mtl::Format &mtlFormat,
180                                             bool *emulatedChannelsOut);
181 MTLColorWriteMask GetEmulatedColorWriteMask(const mtl::Format &mtlFormat);
182 bool IsFormatEmulated(const mtl::Format &mtlFormat);
183 size_t EstimateTextureSizeInBytes(const mtl::Format &mtlFormat,
184                                   size_t width,
185                                   size_t height,
186                                   size_t depth,
187                                   size_t sampleCount,
188                                   size_t numMips);
189 
190 NSUInteger GetMaxRenderTargetSizeForDeviceInBytes(const mtl::ContextDevice &device);
191 NSUInteger GetMaxNumberOfRenderTargetsForDevice(const mtl::ContextDevice &device);
192 bool DeviceHasMaximumRenderTargetSize(id<MTLDevice> device);
193 
194 // Useful to set clear color for texture originally having no alpha in GL, but backend's format
195 // has alpha channel.
196 MTLClearColor EmulatedAlphaClearColor(MTLClearColor color, MTLColorWriteMask colorMask);
197 
198 NSUInteger ComputeTotalSizeUsedForMTLRenderPassDescriptor(const mtl::RenderPassDesc &descriptor,
199                                                           const Context *context,
200                                                           const mtl::ContextDevice &device);
201 
202 NSUInteger ComputeTotalSizeUsedForMTLRenderPipelineDescriptor(
203     const MTLRenderPipelineDescriptor *descriptor,
204     const Context *context,
205     const mtl::ContextDevice &device);
206 
207 gl::Box MTLRegionToGLBox(const MTLRegion &mtlRegion);
208 
209 MipmapNativeLevel GetNativeMipLevel(GLuint level, GLuint base);
210 GLuint GetGLMipLevel(const MipmapNativeLevel &nativeLevel, GLuint base);
211 
212 angle::Result TriangleFanBoundCheck(ContextMtl *context, size_t numTris);
213 
214 angle::Result GetTriangleFanIndicesCount(ContextMtl *context,
215                                          GLsizei vetexCount,
216                                          uint32_t *numElemsOut);
217 
218 angle::Result CreateMslShader(Context *context,
219                               id<MTLLibrary> shaderLib,
220                               NSString *shaderName,
221                               MTLFunctionConstantValues *funcConstants,
222                               AutoObjCPtr<id<MTLFunction>> *shaderOut);
223 
224 angle::Result CreateMslShader(Context *context,
225                               id<MTLLibrary> shaderLib,
226                               NSString *shaderName,
227                               MTLFunctionConstantValues *funcConstants,
228                               id<MTLFunction> *shaderOut);
229 
230 }  // namespace mtl
231 }  // namespace rx
232 
233 #endif /* LIBANGLE_RENDERER_METAL_MTL_UTILS_H_ */
234