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