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 bool enableFastMath, 96 AutoObjCPtr<NSError *> *error); 97 98 AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(id<MTLDevice> metalDevice, 99 const std::string &source, 100 AutoObjCPtr<NSError *> *error); 101 102 AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary( 103 id<MTLDevice> metalDevice, 104 const char *source, 105 size_t sourceLen, 106 NSDictionary<NSString *, NSObject *> *substitutionDictionary, 107 bool enableFastMath, 108 AutoObjCPtr<NSError *> *error); 109 110 AutoObjCPtr<id<MTLLibrary>> CreateShaderLibraryFromBinary( 111 id<MTLDevice> metalDevice, 112 const uint8_t *binarySource, 113 size_t binarySourceLen, 114 NSDictionary<NSString *, NSObject *> *substitutionDictionary, 115 AutoObjCPtr<NSError *> *error); 116 117 bool supportsAppleGPUFamily(id<MTLDevice> device, uint8_t appleFamily); 118 119 bool SupportsMacGPUFamily(id<MTLDevice> device, uint8_t macFamily); 120 121 // Need to define invalid enum value since Metal doesn't define it 122 constexpr MTLTextureType MTLTextureTypeInvalid = static_cast<MTLTextureType>(NSUIntegerMax); 123 static_assert(sizeof(MTLTextureType) == sizeof(NSUInteger), 124 "MTLTextureType is supposed to be based on NSUInteger"); 125 126 constexpr MTLPrimitiveType MTLPrimitiveTypeInvalid = static_cast<MTLPrimitiveType>(NSUIntegerMax); 127 static_assert(sizeof(MTLPrimitiveType) == sizeof(NSUInteger), 128 "MTLPrimitiveType is supposed to be based on NSUInteger"); 129 130 constexpr MTLIndexType MTLIndexTypeInvalid = static_cast<MTLIndexType>(NSUIntegerMax); 131 static_assert(sizeof(MTLIndexType) == sizeof(NSUInteger), 132 "MTLIndexType is supposed to be based on NSUInteger"); 133 134 MTLTextureType GetTextureType(gl::TextureType glType); 135 136 MTLSamplerMinMagFilter GetFilter(GLenum filter); 137 MTLSamplerMipFilter GetMipmapFilter(GLenum filter); 138 MTLSamplerAddressMode GetSamplerAddressMode(GLenum wrap); 139 140 MTLBlendFactor GetBlendFactor(GLenum factor); 141 MTLBlendOperation GetBlendOp(GLenum op); 142 143 MTLCompareFunction GetCompareFunc(GLenum func); 144 MTLStencilOperation GetStencilOp(GLenum op); 145 146 MTLWinding GetFontfaceWinding(GLenum frontFaceMode, bool invert); 147 148 PrimitiveTopologyClass GetPrimitiveTopologyClass(gl::PrimitiveMode mode); 149 MTLPrimitiveType GetPrimitiveType(gl::PrimitiveMode mode); 150 MTLIndexType GetIndexType(gl::DrawElementsType type); 151 152 #if ANGLE_MTL_SWIZZLE_AVAILABLE 153 MTLTextureSwizzle GetTextureSwizzle(GLenum swizzle); 154 #endif 155 156 // Get color write mask for a specified format. Some formats such as RGB565 doesn't have alpha 157 // channel but is emulated by a RGBA8 format, we need to disable alpha write for this format. 158 // - emulatedChannelsOut: if the format is emulated, this pointer will store a true value. 159 MTLColorWriteMask GetEmulatedColorWriteMask(const mtl::Format &mtlFormat, 160 bool *emulatedChannelsOut); 161 MTLColorWriteMask GetEmulatedColorWriteMask(const mtl::Format &mtlFormat); 162 bool IsFormatEmulated(const mtl::Format &mtlFormat); 163 164 NSUInteger GetMaxRenderTargetSizeForDeviceInBytes(id<MTLDevice> device); 165 NSUInteger GetMaxNumberOfRenderTargetsForDevice(id<MTLDevice> device); 166 bool DeviceHasMaximumRenderTargetSize(id<MTLDevice> device); 167 168 // Useful to set clear color for texture originally having no alpha in GL, but backend's format 169 // has alpha channel. 170 MTLClearColor EmulatedAlphaClearColor(MTLClearColor color, MTLColorWriteMask colorMask); 171 172 NSUInteger ComputeTotalSizeUsedForMTLRenderPassDescriptor(const MTLRenderPassDescriptor *descriptor, 173 const Context *context, 174 id<MTLDevice> device); 175 176 NSUInteger ComputeTotalSizeUsedForMTLRenderPipelineDescriptor( 177 const MTLRenderPipelineDescriptor *descriptor, 178 const Context *context, 179 id<MTLDevice> device); 180 181 gl::Box MTLRegionToGLBox(const MTLRegion &mtlRegion); 182 183 MipmapNativeLevel GetNativeMipLevel(GLuint level, GLuint base); 184 GLuint GetGLMipLevel(const MipmapNativeLevel &nativeLevel, GLuint base); 185 186 angle::Result TriangleFanBoundCheck(ContextMtl *context, size_t numTris); 187 188 angle::Result GetTriangleFanIndicesCount(ContextMtl *context, 189 GLsizei vetexCount, 190 uint32_t *numElemsOut); 191 192 angle::Result CreateMslShader(Context *context, 193 id<MTLLibrary> shaderLib, 194 NSString *shaderName, 195 MTLFunctionConstantValues *funcConstants, 196 AutoObjCPtr<id<MTLFunction>> *shaderOut); 197 198 angle::Result CreateMslShader(Context *_Nonnull context, 199 id<MTLLibrary> shaderLib, 200 NSString *_Nonnull shaderName, 201 MTLFunctionConstantValues *_Nullable funcConstants, 202 id<MTLFunction> _Nullable *_Nonnull shaderOut); 203 204 NS_ASSUME_NONNULL_END 205 } // namespace mtl 206 } // namespace rx 207 208 #endif /* LIBANGLE_RENDERER_METAL_MTL_UTILS_H_ */ 209