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> ¯os, 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