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