Type Alias


A block to make a copy of a source texture for filters that can only execute out of place.


typealias MPSCopyAllocator = (MPSKernel, MTLCommandBuffer, MTLTexture) -> MTLTexture


The block takes the following parameters:


A valid pointer to the kernel that is calling the copy allocator.


A valid command buffer that can be used to obtain the device against which to allocate the new texture. You may also enqueue operations on the command buffer to initialize the texture on an encoder allocated in the block. You may not submit, enqueue, or wait for scheduling/completion of the command buffer.


The texture that is providing the source image for the filter. You may wish to use its size and pixel format for the next texture, but you are not required to do so.

The copy allocator returns a new valid texture to use as the destination for the kernel operation. If the calling function succeeds, its texture parameter will be overwritten with a pointer to this texture. If the calling function fails, then the texture will be released before the calling function returns.

Allocating a new texture each time is slow (they take up to 1 ms each). You can recycle old textures (or buffers and make texture from them) and reuse the memory inside the copy allocator block.

If there is any metadata associated with the source texture, such as colorspace information, resource label, CPU cache mode, purgeable state, etc., it may need to be similarly associated with the new texture to avoid losing your metadata.

If the kernel’s clipRect property doesn’t cover the entire image, you may need to copy pixels from the source texture to the new texture, or regions of the next texture will be uninitialized. You can make a command encoder to encode work on the command buffer here, if necessary. It will be scheduled to run immediately before the kernel work. You may call any of the enqueue(), commit(), waitUntilCompleted(), or waitUntilScheduled() methods inside the copy allocator block. Make sure to call endEncoding() on the command encoder so that the command buffer has no active encoder before returning.

Listing 1 shows a minimal copy allocator implementation.

Listing 1

Minimal MPSCopyAllocator Implementation

let copyAllocator: MPSCopyAllocator =
    (kernel: MPSKernel, buffer: MTLCommandBuffer, texture: MTLTexture) -> MTLTexture in
    let descriptor = MTLTextureDescriptor.texture2DDescriptor(
        pixelFormat: texture.pixelFormat,
        width: texture.width,
        height: texture.height,
        mipmapped: false)
    return buffer.device.makeTexture(descriptor: descriptor)