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 // Initialize texture content to black. 37 angle::Result InitializeTextureContents(const gl::Context *context, 38 const TextureRef &texture, 39 const Format &textureObjFormat, 40 const ImageNativeIndex &index); 41 // Same as above but using GPU clear operation instead of CPU. 42 // - channelsToInit parameter controls which channels will get their content initialized. 43 angle::Result InitializeTextureContentsGPU(const gl::Context *context, 44 const TextureRef &texture, 45 const Format &textureObjFormat, 46 const ImageNativeIndex &index, 47 MTLColorWriteMask channelsToInit); 48 49 // Same as above but for a depth/stencil texture. 50 angle::Result InitializeDepthStencilTextureContentsGPU(const gl::Context *context, 51 const TextureRef &texture, 52 const Format &textureObjFormat, 53 const ImageNativeIndex &index); 54 55 // Unified texture's per slice/depth texel reading function 56 angle::Result ReadTexturePerSliceBytes(const gl::Context *context, 57 const TextureRef &texture, 58 size_t bytesPerRow, 59 const gl::Rectangle &fromRegion, 60 const MipmapNativeLevel &mipLevel, 61 uint32_t sliceOrDepth, 62 uint8_t *dataOut); 63 64 angle::Result ReadTexturePerSliceBytesToBuffer(const gl::Context *context, 65 const TextureRef &texture, 66 size_t bytesPerRow, 67 const gl::Rectangle &fromRegion, 68 const MipmapNativeLevel &mipLevel, 69 uint32_t sliceOrDepth, 70 uint32_t dstOffset, 71 const BufferRef &dstBuffer); 72 73 MTLViewport GetViewport(const gl::Rectangle &rect, double znear = 0, double zfar = 1); 74 MTLViewport GetViewportFlipY(const gl::Rectangle &rect, 75 NSUInteger screenHeight, 76 double znear = 0, 77 double zfar = 1); 78 MTLViewport GetViewport(const gl::Rectangle &rect, 79 NSUInteger screenHeight, 80 bool flipY, 81 double znear = 0, 82 double zfar = 1); 83 MTLScissorRect GetScissorRect(const gl::Rectangle &rect, 84 NSUInteger screenHeight = 0, 85 bool flipY = false); 86 87 uint32_t GetDeviceVendorId(id<MTLDevice> metalDevice); 88 89 AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary( 90 const mtl::ContextDevice &metalDevice, 91 const std::string &source, 92 NSDictionary<NSString *, NSObject *> *substitutionDictionary, 93 bool enableFastMath, 94 AutoObjCPtr<NSError *> *error); 95 96 AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(const mtl::ContextDevice &metalDevice, 97 const std::string &source, 98 AutoObjCPtr<NSError *> *error); 99 100 AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary( 101 const mtl::ContextDevice &metalDevice, 102 const char *source, 103 size_t sourceLen, 104 NSDictionary<NSString *, NSObject *> *substitutionDictionary, 105 bool enableFastMath, 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 size_t EstimateTextureSizeInBytes(const mtl::Format &mtlFormat, 162 size_t width, 163 size_t height, 164 size_t depth, 165 size_t sampleCount, 166 size_t numMips); 167 168 NSUInteger GetMaxRenderTargetSizeForDeviceInBytes(const mtl::ContextDevice &device); 169 NSUInteger GetMaxNumberOfRenderTargetsForDevice(const mtl::ContextDevice &device); 170 bool DeviceHasMaximumRenderTargetSize(id<MTLDevice> device); 171 172 // Useful to set clear color for texture originally having no alpha in GL, but backend's format 173 // has alpha channel. 174 MTLClearColor EmulatedAlphaClearColor(MTLClearColor color, MTLColorWriteMask colorMask); 175 176 NSUInteger ComputeTotalSizeUsedForMTLRenderPassDescriptor(const MTLRenderPassDescriptor *descriptor, 177 const Context *context, 178 const mtl::ContextDevice &device); 179 180 NSUInteger ComputeTotalSizeUsedForMTLRenderPipelineDescriptor( 181 const MTLRenderPipelineDescriptor *descriptor, 182 const Context *context, 183 const mtl::ContextDevice &device); 184 185 gl::Box MTLRegionToGLBox(const MTLRegion &mtlRegion); 186 187 MipmapNativeLevel GetNativeMipLevel(GLuint level, GLuint base); 188 GLuint GetGLMipLevel(const MipmapNativeLevel &nativeLevel, GLuint base); 189 190 angle::Result TriangleFanBoundCheck(ContextMtl *context, size_t numTris); 191 192 angle::Result GetTriangleFanIndicesCount(ContextMtl *context, 193 GLsizei vetexCount, 194 uint32_t *numElemsOut); 195 196 angle::Result CreateMslShader(Context *context, 197 id<MTLLibrary> shaderLib, 198 NSString *shaderName, 199 MTLFunctionConstantValues *funcConstants, 200 AutoObjCPtr<id<MTLFunction>> *shaderOut); 201 202 angle::Result CreateMslShader(Context *context, 203 id<MTLLibrary> shaderLib, 204 NSString *shaderName, 205 MTLFunctionConstantValues *funcConstants, 206 id<MTLFunction> *shaderOut); 207 208 } // namespace mtl 209 } // namespace rx 210 211 #endif /* LIBANGLE_RENDERER_METAL_MTL_UTILS_H_ */ 212