objc2-metal-performance-shaders 0.3.2

Bindings to the MetalPerformanceShaders framework
Documentation
//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
use objc2::__framework_prelude::*;
use objc2_metal::*;

use crate::*;

extern_class!(
    /// Dependencies: This depends on Metal.framework
    ///
    /// A MPSPredicate can be used to run MPS kernels subject to a predicate.
    ///
    /// The MPSPredicate defines a way to refrain running a kernel on the GPU
    /// based on values computed on the GPU. That way one can build control flow operations
    /// that do the decisions on the GPU side mitigating the need to synchronize CPU and GPU
    /// execution. The predicate is used with the version of encode calls that take
    /// a object of type
    /// MPSKernelEncodeOptionsas a parameter (
    ///
    /// See: MPSCNNKernel for example).
    /// The code associated with the kernel's encode call is executed on the GPU if and only if
    /// the predicate is considered to be true.
    /// NOTE: It is advisable to release MPSPredicate objects promptly as they take a reference
    /// to a MTLBuffer object and therefore can keep the memory allocated for long periods of time.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpspredicate?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MPSPredicate;
);

extern_conformance!(
    unsafe impl NSObjectProtocol for MPSPredicate {}
);

impl MPSPredicate {
    extern_methods!(
        /// The buffer that is used as the predicate
        #[unsafe(method(predicateBuffer))]
        #[unsafe(method_family = none)]
        pub unsafe fn predicateBuffer(&self) -> Retained<ProtocolObject<dyn MTLBuffer>>;

        /// Location of the predicate in bytes, must be multiple of four.
        ///
        /// If the uint32_t value stored at this location in
        /// predicateBufferis other than zero,
        /// then the predicate is considered to be true and the code is executed on the GPU.
        /// With this property a single MPSPredicate object can be used with multiple different predication
        /// operations.
        /// Default = 0;
        #[unsafe(method(predicateOffset))]
        #[unsafe(method_family = none)]
        pub unsafe fn predicateOffset(&self) -> NSUInteger;

        /// Initializes a MPSPredicate object with a buffer and given offset.
        ///
        /// Parameter `buffer`: The buffer to use as a predicate.
        ///
        /// Parameter `offset`: Byteoffset to the predicate buffer where the predicate is stored.
        ///
        /// Returns: A pointer to the newly initialized MPSPredicate object.
        ///
        /// # Safety
        ///
        /// - `buffer` may need to be synchronized.
        /// - `buffer` may be unretained, you must ensure it is kept alive while in use.
        /// - `buffer` contents should be of the correct type.
        #[unsafe(method(predicateWithBuffer:offset:))]
        #[unsafe(method_family = none)]
        pub unsafe fn predicateWithBuffer_offset(
            buffer: &ProtocolObject<dyn MTLBuffer>,
            offset: NSUInteger,
        ) -> Retained<Self>;

        /// Initializes a MPSPredicate object with a buffer and given offset.
        ///
        /// Parameter `buffer`: The buffer to use as a predicate.
        ///
        /// Parameter `offset`: Byteoffset to the predicate buffer where the predicate is stored.
        ///
        /// Returns: A pointer to the newly initialized MPSPredicate object.
        ///
        /// # Safety
        ///
        /// - `buffer` may need to be synchronized.
        /// - `buffer` may be unretained, you must ensure it is kept alive while in use.
        /// - `buffer` contents should be of the correct type.
        #[unsafe(method(initWithBuffer:offset:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithBuffer_offset(
            this: Allocated<Self>,
            buffer: &ProtocolObject<dyn MTLBuffer>,
            offset: NSUInteger,
        ) -> Retained<Self>;

        /// Initializes a MPSPredicate object for a given device.
        ///
        /// NOTE: The metal buffer used by the resulting MPSPredicate object may be
        /// shared among many MPSPredicate objects and therefore care must be used when
        /// writing to this buffer: writing to any other location in this buffer than the
        /// four bytes at the offset
        /// predicateOffsetresults in undefined behavior.
        ///
        ///
        /// Parameter `device`: The device the predicate is used with
        ///
        /// Returns: A pointer to the newly initialized MPSPredicate object.
        #[unsafe(method(initWithDevice:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithDevice(
            this: Allocated<Self>,
            device: &ProtocolObject<dyn MTLDevice>,
        ) -> Retained<Self>;
    );
}

/// Methods declared on superclass `NSObject`.
impl MPSPredicate {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpsheapprovider?language=objc)
    pub unsafe trait MPSHeapProvider: NSObjectProtocol {
        /// Return a heap of the size indicated
        ///
        /// The heap may be larger than requested.
        /// id
        /// <MTLDevice
        /// > implements this method.
        ///
        /// Parameter `descriptor`: A descriptor for the new heap
        ///
        /// Returns: A new heap of size at least descriptor.size.  If nil is returned, MPS
        /// will use the MPS internal heap cache instead to satisfy the allocation.
        #[unsafe(method(newHeapWithDescriptor:))]
        #[unsafe(method_family = new)]
        unsafe fn newHeapWithDescriptor(
            &self,
            descriptor: &MTLHeapDescriptor,
        ) -> Option<Retained<ProtocolObject<dyn MTLHeap>>>;

        /// Retire a heap
        ///
        /// When MPS is done with the heap, this is called to return the heap to the heap provider
        /// MPS will release the heap after this is called.
        ///
        /// Parameter `heap`: The heap to be retired
        ///
        /// Parameter `seconds`: A hint for how long to cache the heap before retiring it.  See MPSSetHeapCacheDuration().
        #[optional]
        #[unsafe(method(retireHeap:cacheDelay:))]
        #[unsafe(method_family = none)]
        unsafe fn retireHeap_cacheDelay(
            &self,
            heap: &ProtocolObject<dyn MTLHeap>,
            seconds: c_double,
        );
    }
);

extern_class!(
    /// Dependencies: This depends on Metal.framework
    ///
    /// A MPSCommandBuffer object is used to wrap an existing command buffer with MPS specific options.
    ///
    /// A MPS kernel typically operates between a fixed set of inputs and outputs.
    /// The MPSCommandBuffer class provides a way to add further encode-time parameters
    /// to the encode call using the command buffer. Currently the only parameter included in the
    /// MPSCommandBuffer that all MPS kernels support is the the predicate option,
    /// which can be used to pre-empt the kernel from the GPU side.
    /// NOTE: the options that contain metal resources will be referenced by this object and
    /// therefore it is advisable to make the lifetime of this object as short as possible as is the
    /// case for all command buffers.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscommandbuffer?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MPSCommandBuffer;
);

extern_conformance!(
    unsafe impl MTLCommandBuffer for MPSCommandBuffer {}
);

extern_conformance!(
    unsafe impl NSObjectProtocol for MPSCommandBuffer {}
);

impl MPSCommandBuffer {
    extern_methods!(
        /// The Metal Command Buffer that was used to initialize this object.
        #[unsafe(method(commandBuffer))]
        #[unsafe(method_family = none)]
        pub unsafe fn commandBuffer(&self) -> Retained<ProtocolObject<dyn MTLCommandBuffer>>;

        /// The base MTLCommandBuffer underlying the MPSCommandBuffer
        ///
        /// MPSCommandBuffers may wrap other MPSCommandBuffers, in the process
        /// creating what is in effect a stack of predicate objects that may be
        /// pushed or popped by making new MPSCommandBuffers or by calling -commandBuffer.
        /// In some circumstances, it is preferable to use the root command buffer,
        /// particularly when trying to identify the command buffer that will be commited
        /// by -commitAndContinue.
        #[unsafe(method(rootCommandBuffer))]
        #[unsafe(method_family = none)]
        pub unsafe fn rootCommandBuffer(&self) -> Retained<ProtocolObject<dyn MTLCommandBuffer>>;

        /// A GPU predicate object. Default: nil.
        #[unsafe(method(predicate))]
        #[unsafe(method_family = none)]
        pub unsafe fn predicate(&self) -> Option<Retained<MPSPredicate>>;

        /// Setter for [`predicate`][Self::predicate].
        #[unsafe(method(setPredicate:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPredicate(&self, predicate: Option<&MPSPredicate>);

        /// A application supplied object to allocate MTLHeaps for MPS
        ///
        /// By default this is nil, which will use MPS' device level global heap cache to
        /// allocate the heaps. This is a reasonable choice. However, it may be inefficient
        /// if you are keeping your own MTLHeap, since there will be two pessimistically
        /// sized free stores which may be larger than is strictly necessary, and of course
        /// fragmentation across multiple heaps. In such cases, the problem may be solved
        /// either by using MPS' automatically managed heap (simple) or having MPS use
        /// your heap. The heapProvider allows you to implement the second case.  To use
        /// the MPS heap, simply make temporary MPSImages, vectors and matrices.
        ///
        /// If multiple MPSCommandBuffers reference the same MTLCommandBuffer, changing
        /// the heapProvider on one will change the heap provider for all of them.
        #[unsafe(method(heapProvider))]
        #[unsafe(method_family = none)]
        pub unsafe fn heapProvider(&self) -> Option<Retained<ProtocolObject<dyn MPSHeapProvider>>>;

        /// Setter for [`heapProvider`][Self::heapProvider].
        #[unsafe(method(setHeapProvider:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setHeapProvider(
            &self,
            heap_provider: Option<&ProtocolObject<dyn MPSHeapProvider>>,
        );

        /// Initializes a MPSCommandBuffer object with given MTLCommandBuffer.
        /// Once we create this MPSCommandBuffer, any methods utilizing it could call commitAndContinue and so the users original commandBuffer may have been committed.
        /// Please use the rootCommandBuffer method to get the current alive underlying MTLCommandBuffer.
        ///
        /// Returns: A pointer to the newly initialized MPSCommandBuffer object.
        #[unsafe(method(commandBufferWithCommandBuffer:))]
        #[unsafe(method_family = none)]
        pub unsafe fn commandBufferWithCommandBuffer(
            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
        ) -> Retained<Self>;

        /// Initializes a MPSCommandBuffer object from a given command queue.
        ///
        /// Returns: A pointer to the newly initialized MPSCommandBuffer object.
        #[unsafe(method(commandBufferFromCommandQueue:))]
        #[unsafe(method_family = none)]
        pub unsafe fn commandBufferFromCommandQueue(
            command_queue: &ProtocolObject<dyn MTLCommandQueue>,
        ) -> Retained<Self>;

        /// Initializes an empty MPSCommandBuffer object with given MTLCommandBuffer.
        /// Once we create this MPSCommandBuffer, any methods utilizing it could call commitAndContinue and so the users original commandBuffer may have been committed.
        /// Please use the rootCommandBuffer method to get the current alive underlying MTLCommandBuffer.
        ///
        /// Returns: A pointer to the newly initialized MPSCommandBuffer object.
        #[unsafe(method(initWithCommandBuffer:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithCommandBuffer(
            this: Allocated<Self>,
            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
        ) -> Retained<Self>;

        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        /// Commit work encoded so far and continue with a new underlying command buffer
        ///
        /// This method commits the underlying root MTLCommandBuffer, and makes
        /// a new one on the same command queue. The MPS heap is moved forward
        /// to the new command buffer such that temporary objects used by
        /// the previous command buffer can be still be used with the new one.
        ///
        /// This provides a way to move work already encoded into consideration
        /// by the Metal back end sooner. For large workloads, e.g. a neural networking graph
        /// periodically calling -commitAndContinue may allow you to improve CPU / GPU parallelism
        /// without the substantial memory increases associated with double buffering.
        /// It will also help decrease overall latency.
        ///
        /// Any Metal schedule or completion callbacks previously attached to this
        /// object will remain attached to the old command buffer and
        /// will fire as expected as the old command buffer is scheduled and
        /// completes. If your application is relying on such callbacks to coordinate
        /// retain / release of important objects that are needed for work encoded after
        /// -commitAndContinue, your application should retain these objects before
        /// calling commitAndContinue, and attach new release callbacks to this
        /// object with a new completion handler so that they persist through the
        /// lifetime of the new underlying command buffer. You may do this, for example
        /// by adding the objects to a mutable array before calling -commitAndContinue, then
        /// release the mutable array in a new completion callback added after -commitAndContinue.
        ///
        /// Because -commitAndContinue commits the old command buffer then switches to a new one,
        /// some aspects of command buffer completion may surprise unwary developers. For example,
        /// -waitUntilCompleted called immediately after -commitAndContinue asks Metal to wait for
        /// the new command buffer to finish, not the old one. Since the new command buffer presumably
        /// hasn't been committed yet, it is formally a deadlock, resources may leak and Metal may
        /// complain. Your application should ether call -commit before -waitUntilCompleted, or
        /// capture the -rootCommandBuffer from before the call to -commitAndContinue and wait
        /// on that.  Similarly, your application should be sure to use the appropriate command buffer
        /// when querying the [MTLCommandBuffer status] property.
        ///
        /// If the underlying MTLCommandBuffer also implements -commitAndContinue, then the message
        /// will be forwarded to that object instead. In this way, underlying predicate objects and
        /// other state will be preserved.
        #[unsafe(method(commitAndContinue))]
        #[unsafe(method_family = none)]
        pub unsafe fn commitAndContinue(&self);

        /// Prefetch heap into the MPS command buffer heap cache.
        ///
        /// If there is not sufficient free storage in the MPS heap for the command buffer for allocations of total size size,
        /// pre-warm the MPS heap with a new MTLHeap allocation of sufficient size.  If this size turns out to be too small
        /// MPS may ask for more heaps later to cover additional allocations. If heapProvider is not nil, the heapProvider
        /// will be used.
        ///
        /// Parameter `size`: The minimum size of the free store needed
        #[unsafe(method(prefetchHeapForWorkloadSize:))]
        #[unsafe(method_family = none)]
        pub unsafe fn prefetchHeapForWorkloadSize(&self, size: usize);
    );
}

/// Methods declared on superclass `NSObject`.
impl MPSCommandBuffer {
    extern_methods!(
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}