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