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