---
title: MTLCommandBuffer
framework: metal
role: symbol
role_heading: Protocol
path: metal/mtlcommandbuffer
---

# MTLCommandBuffer

A container that stores a sequence of GPU commands that you encode into it.

## Declaration

```swift
protocol MTLCommandBuffer : NSObjectProtocol
```

## Mentioned in

Understanding the Metal 4 core API Setting up a command structure Simplifying GPU resource management with residency sets Tracking the resource residency of argument buffers

## Overview

Overview A command buffer represents a chunk of work for the GPU that stores the commands you encode to it, as well as any resources those commands need. You primarily use a command buffer to: Create command encoders and call their methods to add commands to the buffer Optionally reserve a place for the command buffer in its command queue by enqueuing the command buffer, even before you encode any commands into it Submit, or commit_,_ the contents of the command buffer to the command queue that creates it to run on the GPU device the queue represents Create a command encoder from an MTLCommandQueue instance by calling its makeCommandBuffer() method. Typically, you create one or more command queues when your app launches and then keep them throughout your app’s lifetime. To add commands to an MTLCommandBuffer instance, create an encoder from one of its factory methods, including: An MTLRenderCommandEncoder instance by calling makeRenderCommandEncoder(descriptor:) An MTLComputeCommandEncoder instance by calling makeComputeCommandEncoder(dispatchType:) An MTLBlitCommandEncoder instance by calling makeBlitCommandEncoder() or makeBlitCommandEncoder(descriptor:) An MTLParallelRenderCommandEncoder instance by calling makeParallelRenderCommandEncoder(descriptor:) note: All encoders inherit additional methods from the MTLCommandEncoder. You can use only a single encoder at a time to add commands to a command buffer. To start using a different command encoder, first signal that you’re done with the current encoder by calling its endEncoding() method. Then create another command encoder from the command buffer and continue adding commands to the buffer with the new encoder. Repeat the process until you finish encoding commands to the command buffer and are ready to run the buffer’s contents on the GPU. Then submit the command buffer to the command queue that you used to create it by calling the command buffer’s commit() method. After an app commits a command buffer, you check its status property or block a thread by calling its waitUntilScheduled() or waitUntilCompleted() methods. You also have the option to reserve a place for the command buffer in its command queue by calling the command buffer’s enqueue() method. You can call this method exactly once at any time before you commit the buffer to the queue. If you don’t enqueue a command buffer, it implicitly enqueues itself when you commit it. Each command queue ensures the order that you enqueue its command buffers is the same order the queue schedules them to run on the GPU. tip: Establish an order of execution for multiple command buffers you encode in parallel by first calling their enqueue() methods in that order. For example, a multithreaded app might set the GPU’s execution order for a sequence of related subtasks by: Creating a command buffer for each subtask Enqueuing the command buffers in the proper order on a single thread Encoding commands to each buffer on a separate thread and then committing it

## Topics

### Creating command encoders

- [Command encoder factory methods](metal/command-encoder-factory-methods.md)

### Attaching residency sets

- [useResidencySet(_:)](metal/mtlcommandbuffer/useresidencyset(_:).md)
- [useResidencySets(_:)](metal/mtlcommandbuffer/useresidencysets(_:).md)

### Synchronizing passes with events

- [encodeWaitForEvent(_:value:)](metal/mtlcommandbuffer/encodewaitforevent(_:value:).md)
- [encodeSignalEvent(_:value:)](metal/mtlcommandbuffer/encodesignalevent(_:value:).md)

### Presenting a drawable

- [present(_:)](metal/mtlcommandbuffer/present(_:).md)
- [present(_:atTime:)](metal/mtlcommandbuffer/present(_:attime:).md)
- [present(_:afterMinimumDuration:)](metal/mtlcommandbuffer/present(_:afterminimumduration:).md)

### Registering state change handlers

- [addScheduledHandler(_:)](metal/mtlcommandbuffer/addscheduledhandler(_:).md)
- [addCompletedHandler(_:)](metal/mtlcommandbuffer/addcompletedhandler(_:).md)
- [MTLCommandBufferHandler](metal/mtlcommandbufferhandler.md)

### Submitting a command buffer

- [enqueue()](metal/mtlcommandbuffer/enqueue().md)
- [commit()](metal/mtlcommandbuffer/commit().md)

### Waiting for state changes

- [waitUntilScheduled()](metal/mtlcommandbuffer/waituntilscheduled().md)
- [waitUntilCompleted()](metal/mtlcommandbuffer/waituntilcompleted().md)

### Troubleshooting a command buffer

- [status](metal/mtlcommandbuffer/status.md)
- [MTLCommandBufferStatus](metal/mtlcommandbufferstatus.md)
- [Command buffer debugging](metal/command-buffer-debugging.md)

### Instance Methods

- [completed()](metal/mtlcommandbuffer/completed().md)
- [scheduled()](metal/mtlcommandbuffer/scheduled().md)

## Relationships

### Inherits From

- [NSObjectProtocol](objectivec/nsobjectprotocol.md)

## See Also

### Submitting work to a GPU with Metal

- [Setting up a command structure](metal/setting-up-a-command-structure.md)
- [MTLCommandQueue](metal/mtlcommandqueue.md)
- [MTLCommandQueueDescriptor](metal/mtlcommandqueuedescriptor.md)
- [MTLCommandBufferDescriptor](metal/mtlcommandbufferdescriptor.md)
- [MTLCommandBufferError](metal/mtlcommandbuffererror-swift.struct.md)
- [MTLCommandEncoder](metal/mtlcommandencoder.md)
