<!--
{
  "documentType" : "article",
  "framework" : "Metal",
  "identifier" : "/documentation/Metal/resource-loading",
  "metadataVersion" : "0.1.0",
  "role" : "collectionGroup",
  "title" : "Resource loading"
}
-->

# Resource loading

Load assets in your games and apps quickly by running a dedicated input/output queue alongside your GPU tasks.

## Discussion

Metal 3 adds input/output command queues and buffers that make the most of a device’s storage hardware, including flash storage and the unified memory architecture of Apple silicon, when available. When you run a dedicated input/output queue alongside your GPU tasks, you can synchronize them with Metal shared events. With this approach, you can minimize load screen times by fetching the essential assets first and streaming the rest as you need them. You can also start multiple input/output command buffers to load different asset batches and later cancel the ones you don’t need. Ensure that time-sensitive assets, such as sound effects, load with lower latency by running those command buffers on higher-priority queues that you create.

First, create [`MTLIOCommandQueue`](/documentation/Metal/MTLIOCommandQueue) instances by configuring an [`MTLIOCommandQueueDescriptor`](/documentation/Metal/MTLIOCommandQueueDescriptor) instance and passing it to an [`MTLDevice`](/documentation/Metal/MTLDevice) instance’s [`makeIOCommandQueue(descriptor:)`](/documentation/Metal/MTLDevice/makeIOCommandQueue(descriptor:)) method.

```swift
// Create a Metal I/O command queue.
let commandQueueDescriptor = MTLIOCommandQueueDescriptor()

commandQueueDescriptor.type = .concurrent
commandQueueDescriptor.priority = .normal

let ioCommandQueue = try device.makeIOCommandQueue(descriptor:
                                                    commandQueueDescriptor)
```

For each queue, create one or more [`MTLIOCommandBuffer`](/documentation/Metal/MTLIOCommandBuffer) instances by calling the queue’s [`makeCommandBuffer()`](/documentation/Metal/MTLIOCommandQueue/makeCommandBuffer()) or [`makeCommandBufferWithUnretainedReferences()`](/documentation/Metal/MTLIOCommandQueue/makeCommandBufferWithUnretainedReferences()) method. For each command buffer, load the assets you want by calling any of the [`MTLIOCommandBuffer`](/documentation/Metal/MTLIOCommandBuffer) protocol’s load methods. For example:

- The [`load(_:offset:size:sourceHandle:sourceHandleOffset:)`](/documentation/Metal/MTLIOCommandBuffer/load(_:offset:size:sourceHandle:sourceHandleOffset:)) method loads an asset into an [`MTLBuffer`](/documentation/Metal/MTLBuffer).
- The [`load(_:slice:level:size:sourceBytesPerRow:sourceBytesPerImage:destinationOrigin:sourceHandle:sourceHandleOffset:)`](/documentation/Metal/MTLIOCommandBuffer/load(_:slice:level:size:sourceBytesPerRow:sourceBytesPerImage:destinationOrigin:sourceHandle:sourceHandleOffset:)) method loads an asset into an [`MTLTexture`](/documentation/Metal/MTLTexture).
- The [`loadBytes(_:size:sourceHandle:sourceHandleOffset:)`](/documentation/Metal/MTLIOCommandBuffer/loadBytes(_:size:sourceHandle:sourceHandleOffset:)) method loads an asset, such as an audio file, into a CPU-accessible memory buffer.

```swift
// Create a Metal I/O command buffer.
let ioCommandBuffer = ioCommandQueue.makeCommandBuffer()

// Encode a command that loads a texture.
ioCommandBuffer.load(texture,
                     slice: 0,
                     level: 0,
                     size: textureSize,
                     sourceBytesPerRow: bytesPerRow,
                     sourceBytesPerImage: bytesPerImage,
                     destinationOrigin: origin,
                     sourceHandle: fileHandle,
                     sourceHandleOffset: 0)

// Encode a command that loads a buffer.
ioCommandBuffer.load(buffer,
                     offset: 0,
                     size: bufferSize,
                     sourceHandle: fileHandle,
                     sourceHandleOffset: 0)

// Submit the command buffer to run.
ioCommandBuffer.commit()
```

For each asset, create an [`MTLIOFileHandle`](/documentation/Metal/MTLIOFileHandle) instance using the input/output command buffer’s load methods. To create a file handle for your asset, call an [`MTLDevice`](/documentation/Metal/MTLDevice) instance’s [`makeIOHandle(url:)`](/documentation/Metal/MTLDevice/makeIOHandle(url:)) or [`makeIOHandle(url:compressionMethod:)`](/documentation/Metal/MTLDevice/makeIOHandle(url:compressionMethod:)) method.

```swift
func createHandleForFile(at url: URL, with device: MTLDevice) -> MTLIOFileHandle? {
    return try? device.makeIOHandle(url: url)
}
```

> Note:
> You need to create each file handle using the same ``doc://com.apple.metal/documentation/Metal/MTLDevice`` instance that created the ``doc://com.apple.metal/documentation/Metal/MTLIOCommandQueue`` and ``doc://com.apple.metal/documentation/Metal/MTLIOCommandBuffer`` instances that load the files.

To help minimize your appʼs storage footprint, compress your assets at development time. First, create a new compression context with the [`MTLIOCreateCompressionContext`](/documentation/Metal/MTLIOCreateCompressionContext) function. Then, add data for an asset to the compression context using the [`MTLIOCompressionContextAppendData(_:_:_:)`](/documentation/Metal/MTLIOCompressionContextAppendData(_:_:_:)) function. Finally, call the  [`MTLIOFlushAndDestroyCompressionContext(_:)`](/documentation/Metal/MTLIOFlushAndDestroyCompressionContext(_:)) function to save the context to a compressed file that you add to your project.

## Topics

### I/O command queues

[`MTLIOCommandQueue`](/documentation/Metal/MTLIOCommandQueue)

A command queue that schedules input/output commands for reading files in the file system, and writing to GPU resources and memory.

[`MTLIOCommandQueueDescriptor`](/documentation/Metal/MTLIOCommandQueueDescriptor)

A configuration template you use to create a new input/output command queue.

[`MTLIOPriority`](/documentation/Metal/MTLIOPriority)

Designates the priority for a new input/output command queue.

[`MTLIOCommandQueueType`](/documentation/Metal/MTLIOCommandQueueType)

Designates the queue type for a new input/output command queue.

[`MTLIOScratchBufferAllocator`](/documentation/Metal/MTLIOScratchBufferAllocator)

A protocol your app implements to provide scratch memory to an input/output command queue.

[`MTLIOScratchBuffer`](/documentation/Metal/MTLIOScratchBuffer)

A protocol your app implements that wraps a Metal buffer instance to serve as scratch memory for an input/output command queue.

### I/O command buffers

[`MTLIOCommandBuffer`](/documentation/Metal/MTLIOCommandBuffer)

A command buffer that contains input/output commands that work with files in the file systems and Metal resources.

[`MTLIOFileHandle`](/documentation/Metal/MTLIOFileHandle)

Represents a raw or compressed file, such as a resource asset file in your app’s bundle.

[`MTLIOCommandBufferHandler`](/documentation/Metal/MTLIOCommandBufferHandler)

A convenience type that defines the signature of an input/output command buffer’s completion handler.

[`MTLIOStatus`](/documentation/Metal/MTLIOStatus)

Represents the state of an input/output command buffer.

[`MTLIOError.Code`](/documentation/Metal/MTLIOError-swift.struct/Code)

The error codes for creating an input/output file handle.

[`MTLIOErrorDomain`](/documentation/Metal/MTLIOErrorDomain)

The domain for input/output command queue errors.

### Asset compression

[`MTLIOCreateCompressionContext(_:_:_:)`](/documentation/Metal/MTLIOCreateCompressionContext(_:_:_:))

Creates a compression context that you use to compress data into a single file.

[`MTLIOCreateCompressionContext`](/documentation/Metal/MTLIOCreateCompressionContext)

Creates a compression context that you use to compress data into a single file.

[`MTLIOCompressionMethod`](/documentation/Metal/MTLIOCompressionMethod)

The compression codecs that Metal supports for input/output handles.

[`MTLIOCompressionContextDefaultChunkSize()`](/documentation/Metal/MTLIOCompressionContextDefaultChunkSize())

Returns a compression chunk size you can use as a default for creating a compression context.

[`MTLIOCompressionContext`](/documentation/Metal/MTLIOCompressionContext)

A pointer that represents the state of a file compression session in progress.

[`MTLIOCompressionContextAppendData(_:_:_:)`](/documentation/Metal/MTLIOCompressionContextAppendData(_:_:_:))

Adds data to a compression context.

[`MTLIOFlushAndDestroyCompressionContext(_:)`](/documentation/Metal/MTLIOFlushAndDestroyCompressionContext(_:))

Finishes compressing and saves the file that a compression context represents.

[`MTLIOCompressionStatus`](/documentation/Metal/MTLIOCompressionStatus)

Represents the final state of a compression context.



---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)