結論:iOS 12 Metal 框架最大變化是引入MTLIndirectCommandBuffer(Encoder)
,目標是提升性能。第二重要更新是引入MTLEvent
。ios
MTLFeatureSet_iOS_GPUFamily1_v5 API_AVAILABLE(ios(12.0)) API_UNAVAILABLE(macos, tvos) = 12,
MTLFeatureSet_iOS_GPUFamily2_v5 API_AVAILABLE(ios(12.0)) API_UNAVAILABLE(macos, tvos) = 13,
MTLFeatureSet_iOS_GPUFamily3_v4 API_AVAILABLE(ios(12.0)) API_UNAVAILABLE(macos, tvos) = 14,
MTLFeatureSet_iOS_GPUFamily4_v2 API_AVAILABLE(ios(12.0)) API_UNAVAILABLE(macos, tvos) = 15,
MTLFeatureSet_iOS_GPUFamily5_v1 API_AVAILABLE(ios(12.0)) API_UNAVAILABLE(macos, tvos) = 16,
- (NSUInteger)minimumTextureBufferAlignmentForPixelFormat:(MTLPixelFormat)format API_AVAILABLE(macos(10.14), ios(12.0));
@property (readonly) NSUInteger maxArgumentBufferSamplerCount API_AVAILABLE(macos(10.14), ios(12.0));
- (nullable id <MTLIndirectCommandBuffer>)newIndirectCommandBufferWithDescriptor:(MTLIndirectCommandBufferDescriptor*)descriptor maxCommandCount:(NSUInteger)maxCount options:(MTLResourceOptions)options API_AVAILABLE(macos(10.14), ios(12.0));
- (nullable id <MTLEvent>)newEvent API_AVAILABLE(macos(10.14), ios(12.0));
- (nullable id <MTLSharedEvent>)newSharedEvent API_AVAILABLE(macos(10.14), ios(12.0));
- (nullable id <MTLSharedEvent>)newSharedEventWithHandle:(MTLSharedEventHandle *)sharedEventHandle API_AVAILABLE(macos(10.14), ios(12.0));
複製代碼
typedef NS_ENUM(NSUInteger, MTLDispatchType){
MTLDispatchTypeSerial,
MTLDispatchTypeConcurrent,
}API_AVAILABLE(macos(10.14), ios(12.0));
- (nullable id<MTLComputeCommandEncoder>)computeCommandEncoderWithDispatchType:(MTLDispatchType) dispatchType API_AVAILABLE(macos(10.14), ios(12.0));
- (void)encodeWaitForEvent:(id <MTLEvent>)event value:(uint64_t)value API_AVAILABLE(macos(10.14), ios(12.0));
- (void)encodeSignalEvent:(id <MTLEvent>)event value:(uint64_t)value API_AVAILABLE(macos(10.14), ios(12.0));
複製代碼
- (void)setViewports:(const MTLViewport [__nonnull])viewports count:(NSUInteger)count API_AVAILABLE(macos(10.13), ios(12.0));
- (void)setScissorRects:(const MTLScissorRect [__nonnull])scissorRects count:(NSUInteger)count API_AVAILABLE(macos(10.13), ios(12.0));
-(void)drawPatches:(NSUInteger)numberOfPatchControlPoints patchIndexBuffer:(nullable id <MTLBuffer>)patchIndexBuffer patchIndexBufferOffset:(NSUInteger)patchIndexBufferOffset indirectBuffer:(id <MTLBuffer>)indirectBuffer indirectBufferOffset:(NSUInteger)indirectBufferOffset API_AVAILABLE(macos(10.12), ios(12.0));
-(void)drawIndexedPatches:(NSUInteger)numberOfPatchControlPoints patchIndexBuffer:(nullable id <MTLBuffer>)patchIndexBuffer patchIndexBufferOffset:(NSUInteger)patchIndexBufferOffset controlPointIndexBuffer:(id <MTLBuffer>)controlPointIndexBuffer controlPointIndexBufferOffset:(NSUInteger)controlPointIndexBufferOffset indirectBuffer:(id <MTLBuffer>)indirectBuffer indirectBufferOffset:(NSUInteger)indirectBufferOffset API_AVAILABLE(macos(10.12), ios(12.0));
- (void)executeCommandsInBuffer:(id<MTLIndirectCommandBuffer>)indirectCommandBuffer withRange:(NSRange)executionRange API_AVAILABLE(macos(10.14), ios(12.0));
複製代碼
typedef NS_ENUM(NSUInteger, MTLMultisampleStencilResolveFilter)
{
/*!
@constant MTLMultisampleStencilResolveFilterSample0
@abstract The stencil sample corresponding to sample 0. This is the default behavior.
*/
MTLMultisampleStencilResolveFilterSample0 = 0,
/*!
@constant MTLMultisampleStencilResolveFilterDepthResolvedSample
@abstract The stencil sample corresponding to whichever depth sample is selected by the depth resolve filter. If depth resolve is not enabled, the stencil sample is chosen based on what a depth resolve filter would have selected.
*/
MTLMultisampleStencilResolveFilterDepthResolvedSample = 1,
} API_AVAILABLE(macos(10.14), ios(12.0));
@property (nonatomic) MTLMultisampleStencilResolveFilter stencilResolveFilter API_AVAILABLE(macos(10.14), ios(12.0));
@property (nonatomic) NSUInteger renderTargetArrayLength API_AVAILABLE(macos(10.11), ios(12.0));
複製代碼
typedef NS_ENUM(NSUInteger, MTLPrimitiveTopologyClass) {
MTLPrimitiveTopologyClassUnspecified = 0,
MTLPrimitiveTopologyClassPoint = 1,
MTLPrimitiveTopologyClassLine = 2,
MTLPrimitiveTopologyClassTriangle = 3,
} API_AVAILABLE(macos(10.11), ios(12.0));
@property (readwrite, nonatomic) MTLPrimitiveTopologyClass inputPrimitiveTopology API_AVAILABLE(macos(10.11), ios(12.0));
@property (readwrite, nonatomic) BOOL supportIndirectCommandBuffers API_AVAILABLE(macos(10.14), ios(12.0));
@property (readonly) BOOL supportIndirectCommandBuffers API_AVAILABLE(macos(10.14), ios(12.0));
@property (readwrite, nonatomic) NSUInteger maxTotalThreadsPerThreadgroup API_AVAILABLE(ios(12.0)) API_UNAVAILABLE(macos);
複製代碼
MTLTextureTypeTextureBuffer API_AVAILABLE(macos(10.14), ios(12.0)) = 9
+ (MTLTextureDescriptor*)textureBufferDescriptorWithPixelFormat:(MTLPixelFormat)pixelFormat
width:(NSUInteger)width
resourceOptions:(MTLResourceOptions)resourceOptions
usage:(MTLTextureUsage)usage API_AVAILABLE(macos(10.14), ios(12.0));
@property (readwrite, nonatomic) BOOL allowGPUOptimizedContents API_AVAILABLE(macos(10.14), ios(12.0));
@property (readonly) BOOL allowGPUOptimizedContents API_AVAILABLE(macos(10.14), ios(12.0));
複製代碼
- (void)optimizeContentsForGPUAccess:(id<MTLTexture>)texture API_AVAILABLE(macos(10.14), ios(12.0));
- (void)optimizeContentsForGPUAccess:(id<MTLTexture>)texture slice:(NSUInteger)slice level:(NSUInteger)level API_AVAILABLE(macos(10.14), ios(12.0));
- (void)optimizeContentsForCPUAccess:(id<MTLTexture>)texture API_AVAILABLE(macos(10.14), ios(12.0));
- (void)optimizeContentsForCPUAccess:(id<MTLTexture>)texture slice:(NSUInteger)slice level:(NSUInteger)level API_AVAILABLE(macos(10.14), ios(12.0));
- (void) resetCommandsInBuffer: (id<MTLIndirectCommandBuffer>)buffer withRange:(NSRange)range API_AVAILABLE(macos(10.14), ios(12.0));
- (void)copyIndirectCommandBuffer:(id <MTLIndirectCommandBuffer>)source sourceRange:(NSRange)sourceRange
destination:(id <MTLIndirectCommandBuffer>)destination destinationIndex:(NSUInteger)destinationIndex API_AVAILABLE(macos(10.14), ios(12.0));
- (void)optimizeIndirectCommandBuffer:(id <MTLIndirectCommandBuffer>)indirectCommandBuffer withRange:(NSRange)range API_AVAILABLE(macos(10.14), ios(12.0));
複製代碼
typedef struct {
uint32_t stageInOrigin[3];
uint32_t stageInSize[3];
} MTLStageInRegionIndirectArguments API_AVAILABLE(macos(10.14), ios(12.0));
@property (readonly) MTLDispatchType dispatchType API_AVAILABLE(macos(10.14), ios(12.0));
-(void)memoryBarrierWithScope:(MTLBarrierScope)scope API_AVAILABLE(macos(10.14), ios(12.0));
- (void)memoryBarrierWithResources:(const id<MTLResource> __nonnull [__nonnull])resources count:(NSUInteger)count API_AVAILABLE(macos(10.14), ios(12.0));
複製代碼
@property (readwrite, nonatomic) NSUInteger maxTotalThreadsPerThreadgroup API_AVAILABLE(macos(10.14), ios(12.0));
複製代碼
- (void)setIndirectCommandBuffer:(nullable id <MTLIndirectCommandBuffer>)indirectCommandBuffer atIndex:(NSUInteger)index API_AVAILABLE(macos(10.14), ios(12.0));
- (void)setIndirectCommandBuffers:(const id <MTLIndirectCommandBuffer> __nullable [__nonnull])buffers withRange:(NSRange)range API_AVAILABLE(macos(10.14), ios(12.0));
複製代碼
typedef NS_OPTIONS(NSUInteger, MTLIndirectCommandType) {
MTLIndirectCommandTypeDraw = (1 << 0),
MTLIndirectCommandTypeDrawIndexed = (1 << 1),
MTLIndirectCommandTypeDrawPatches = (1 << 2),
MTLIndirectCommandTypeDrawIndexedPatches = (1 << 3) ,
} API_AVAILABLE(macos(10.14), ios(12.0));
/*!
@abstract
Describes the limits and features that can be used in an indirect command
*/
MTL_EXPORT API_AVAILABLE(macos(10.14), ios(12.0))
@interface MTLIndirectCommandBufferDescriptor : NSObject
/*!
@abstract
A bitfield of the command types that be encoded.
@discussion
MTLCommandTypeDispatch cannot be mixed with any other command type.
*/
@property (readwrite, nonatomic) MTLIndirectCommandType commandTypes;
/*!
@abstract
Whether the render or compute pipeline are inherited from the encoder
*/
@property (readwrite, nonatomic) BOOL inheritPipelineState API_AVAILABLE(macos(10.14)) API_UNAVAILABLE(ios);
/*!
@abstract
Whether the render or compute pipeline can set arguments.
*/
@property (readwrite, nonatomic) BOOL inheritBuffers;
/*!
@abstract
The maximum bind index of vertex argument buffers that can be set per command.
*/
@property (readwrite, nonatomic) NSUInteger maxVertexBufferBindCount;
/*!
@absract
The maximum bind index of fragment argument buffers that can be set per command.
*/
@property (readwrite, nonatomic) NSUInteger maxFragmentBufferBindCount;
@end
API_AVAILABLE(macos(10.14), ios(12.0))
@protocol MTLIndirectCommandBuffer <MTLResource>
@property (readonly) NSUInteger size;
-(void)resetWithRange:(NSRange)range;
- (id <MTLIndirectRenderCommand>)indirectRenderCommandAtIndex:(NSUInteger)commandIndex;
@end
複製代碼
API_AVAILABLE(macos(10.14), ios(12.0))
@protocol MTLIndirectRenderCommand <NSObject>
- (void)setRenderPipelineState:(id <MTLRenderPipelineState>)pipelineState API_AVAILABLE(macos(10.14)) API_UNAVAILABLE(ios);
- (void)setVertexBuffer:(id <MTLBuffer>)buffer offset:(NSUInteger)offset atIndex:(NSUInteger)index;
- (void)setFragmentBuffer:(id <MTLBuffer>)buffer offset:(NSUInteger)offset atIndex:(NSUInteger)index;
- (void) drawPatches:(NSUInteger)numberOfPatchControlPoints patchStart:(NSUInteger)patchStart patchCount:(NSUInteger)patchCount patchIndexBuffer:(nullable id <MTLBuffer>)patchIndexBuffer
patchIndexBufferOffset:(NSUInteger)patchIndexBufferOffset instanceCount:(NSUInteger)instanceCount baseInstance:(NSUInteger)baseInstance
tessellationFactorBuffer:(id <MTLBuffer>)buffer tessellationFactorBufferOffset:(NSUInteger)offset tessellationFactorBufferInstanceStride:(NSUInteger)instanceStride;
- (void)drawIndexedPatches:(NSUInteger)numberOfPatchControlPoints patchStart:(NSUInteger)patchStart patchCount:(NSUInteger)patchCount patchIndexBuffer:(nullable id <MTLBuffer>)patchIndexBuffer
patchIndexBufferOffset:(NSUInteger)patchIndexBufferOffset controlPointIndexBuffer:(id <MTLBuffer>)controlPointIndexBuffer
controlPointIndexBufferOffset:(NSUInteger)controlPointIndexBufferOffset instanceCount:(NSUInteger)instanceCount
baseInstance:(NSUInteger)baseInstance tessellationFactorBuffer:(id <MTLBuffer>)buffer
tessellationFactorBufferOffset:(NSUInteger)offset tessellationFactorBufferInstanceStride:(NSUInteger)instanceStride;
- (void)drawPrimitives:(MTLPrimitiveType)primitiveType vertexStart:(NSUInteger)vertexStart vertexCount:(NSUInteger)vertexCount instanceCount:(NSUInteger)instanceCount baseInstance:(NSUInteger)baseInstance;
- (void)drawIndexedPrimitives:(MTLPrimitiveType)primitiveType indexCount:(NSUInteger)indexCount indexType:(MTLIndexType)indexType indexBuffer:(id <MTLBuffer>)indexBuffer indexBufferOffset:(NSUInteger)indexBufferOffset instanceCount:(NSUInteger)instanceCount baseVertex:(NSInteger)baseVertex baseInstance:(NSUInteger)baseInstance;
- (void)reset;
@end
複製代碼
API_AVAILABLE(macos(10.14), ios(12.0))
@protocol MTLEvent <NSObject>
/*!
@property device
@abstract The device this event can be used with. Will be nil when the event is shared across devices (i.e. MTLSharedEvent).
*/
@property (nullable, readonly) id <MTLDevice> device;
/*!
@property label
@abstract A string to help identify this object.
*/
@property (nullable, copy, atomic) NSString *label;
@end
/*!
@class MTLSharedEventListener
@abstract This class provides a simple interface for handling the dispatching of MTLSharedEvent notifications from Metal.
*/
MTL_EXPORT API_AVAILABLE(macos(10.14), ios(12.0))
@interface MTLSharedEventListener : NSObject
- (instancetype)init NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDispatchQueue:(dispatch_queue_t)dispatchQueue NS_DESIGNATED_INITIALIZER;
@property (nonnull, readonly) dispatch_queue_t dispatchQueue;
@end
@class MTLSharedEventHandle;
@protocol MTLSharedEvent;
typedef void (^MTLSharedEventNotificationBlock)(id <MTLSharedEvent>, uint64_t value);
API_AVAILABLE(macos(10.14), ios(12.0))
@protocol MTLSharedEvent <MTLEvent>
// When the event's signaled value reaches value or higher, invoke the block on the dispatch queue owned by the listener.
- (void)notifyListener:(MTLSharedEventListener *)listener atValue:(uint64_t)value block:(MTLSharedEventNotificationBlock)block;
// Convenience method for creating a shared event handle that may be passed to other processes via XPC.
- (MTLSharedEventHandle *)newSharedEventHandle;
@property (readwrite) uint64_t signaledValue; // Read or set signaled value
@end
// MTLSharedEventHandle objects may be passed between processes via XPC connections and then used to recreate
// a MTLSharedEvent via an existing MTLDevice.
MTL_EXPORT API_AVAILABLE(macos(10.14), ios(12.0))
@interface MTLSharedEventHandle : NSObject <NSSecureCoding>
{
struct MTLSharedEventHandlePrivate *_priv;
}
@property (readonly, nullable) NSString *label;
@end
複製代碼