<!--
{
  "availability" : [
    "iOS: 8.0.0 -",
    "iPadOS: 8.0.0 -",
    "macCatalyst: 13.1.0 -",
    "macOS: 10.11.0 -",
    "tvOS: -",
    "visionOS: 1.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "Metal",
  "identifier" : "/documentation/Metal/MTLRenderCommandEncoder",
  "metadataVersion" : "0.1.0",
  "role" : "Protocol",
  "symbol" : {
    "kind" : "Protocol",
    "modules" : [
      "Metal"
    ],
    "preciseIdentifier" : "c:objc(pl)MTLRenderCommandEncoder"
  },
  "title" : "MTLRenderCommandEncoder"
}
-->

# MTLRenderCommandEncoder

Encodes configuration and draw commands for a single render pass into a command buffer.

```
protocol MTLRenderCommandEncoder : MTLCommandEncoder
```

## Overview

A render pass draws a scene, or a component within a scene, to its render *attachments*, the outputs of a render pass.
You can render to those outputs with various approaches, including techniques that apply the following:

- Primitive drawing
- Mesh drawing
- Ray tracing
- Dispatching tile shaders

To create an [`MTLRenderCommandEncoder`](/documentation/Metal/MTLRenderCommandEncoder) instance, call the [`makeRenderCommandEncoder(descriptor:)`](/documentation/Metal/MTLCommandBuffer/makeRenderCommandEncoder(descriptor:)) method of an [`MTLCommandBuffer`](/documentation/Metal/MTLCommandBuffer) instance, or the [`makeRenderCommandEncoder()`](/documentation/Metal/MTLParallelRenderCommandEncoder/makeRenderCommandEncoder()) method of an [`MTLParallelRenderCommandEncoder`](/documentation/Metal/MTLParallelRenderCommandEncoder) instance.

To configure the render pass for your first drawing commands, start with a pipeline state by passing an [`MTLRenderPipelineState`](/documentation/Metal/MTLRenderPipelineState) instance to the encoder’s [`setRenderPipelineState(_:)`](/documentation/Metal/MTLRenderCommandEncoder/setRenderPipelineState(_:)) method. You create the pipeline states your render pass needs, typically ahead of time, by calling one or more [`MTLDevice`](/documentation/Metal/MTLDevice) methods (see [Pipeline state creation](/documentation/Metal/pipeline-state-creation)).

> Tip:
> Avoid visual stutter by creating pipeline states at a noncritical time, such as during launch, because of the time it can take to make them.

Configure other encoder settings by calling the methods on the [Render pass configuration](/documentation/Metal/render-pass-configuration) page.
For example, you may need to configure the pass’s viewport, its scissor rectangle, and the settings for depth and stencil tests.

Assign resources, such as buffers and textures, for the shaders that depend on them. For more information, see the shader-specific pages in the resource preparation section, such as [Vertex shader resource preparation commands](/documentation/Metal/vertex-shader-resource-preparation-commands) and [Fragment shader resource preparation commands](/documentation/Metal/fragment-shader-resource-preparation-commands). If your shaders access resources through an argument buffer, make those resources *resident* in GPU memory by calling the methods on the [Argument buffer resource preparation commands](/documentation/Metal/argument-buffer-resource-preparation-commands) page.

Encode drawing commands after you configure the state and resources the commands depend on.
The encoder maintains its current state and applies it to all subsequent draw commands.
For drawing commands that need different states or resources, reconfigure the render pass appropriately and then encode those draw commands.
Repeat the process for each batch of drawing commands that depend on the same render pass configuration and resources.

When you finish encoding the render pass’s commands, finalize it into the command buffer by calling the encoder’s [`endEncoding()`](/documentation/Metal/MTLCommandEncoder/endEncoding()) method.

### Command stages

Most render commands apply to one or more stages within a pass.
The following table shows which stages apply to each command:

|Function                                                                                                                                                                                                                                                            |MTLStages                                                                                                                                                                                                       |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/drawPrimitives(type:vertexStart:vertexCount:)``                                                                                                                                                 |``doc://com.apple.metal/documentation/Metal/MTLStages/vertex``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``                                                                       |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/drawPrimitives(type:vertexStart:vertexCount:instanceCount:)``                                                                                                                                   |``doc://com.apple.metal/documentation/Metal/MTLStages/vertex``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``                                                                       |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/drawPrimitives(type:vertexStart:vertexCount:instanceCount:baseInstance:)``                                                                                                                      |``doc://com.apple.metal/documentation/Metal/MTLStages/vertex``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``                                                                       |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/drawPrimitives(type:indirectBuffer:indirectBufferOffset:)``                                                                                                                                     |``doc://com.apple.metal/documentation/Metal/MTLStages/vertex``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``                                                                       |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/drawIndexedPrimitives(type:indexCount:indexType:indexBuffer:indexBufferOffset:)``                                                                                                               |``doc://com.apple.metal/documentation/Metal/MTLStages/vertex``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``                                                                       |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/drawIndexedPrimitives(type:indexCount:indexType:indexBuffer:indexBufferOffset:instanceCount:)``                                                                                                 |``doc://com.apple.metal/documentation/Metal/MTLStages/vertex``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``                                                                       |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/drawIndexedPrimitives(type:indexCount:indexType:indexBuffer:indexBufferOffset:instanceCount:baseVertex:baseInstance:)``                                                                         |``doc://com.apple.metal/documentation/Metal/MTLStages/vertex``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``                                                                       |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/drawIndexedPrimitives(type:indexType:indexBuffer:indexBufferOffset:indirectBuffer:indirectBufferOffset:)``                                                                                      |``doc://com.apple.metal/documentation/Metal/MTLStages/vertex``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``                                                                       |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/drawMeshThreads(_:threadsPerObjectThreadgroup:threadsPerMeshThreadgroup:)``                                                                                                                     |``doc://com.apple.metal/documentation/Metal/MTLStages/object``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/mesh``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``|
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/drawMeshThreadgroups(_:threadsPerObjectThreadgroup:threadsPerMeshThreadgroup:)``                                                                                                                |``doc://com.apple.metal/documentation/Metal/MTLStages/object``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/mesh``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``|
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/drawMeshThreadgroups(indirectBuffer:indirectBufferOffset:threadsPerObjectThreadgroup:threadsPerMeshThreadgroup:)``                                                                              |``doc://com.apple.metal/documentation/Metal/MTLStages/object``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/mesh``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``|
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/drawPatches(numberOfPatchControlPoints:patchStart:patchCount:patchIndexBuffer:patchIndexBufferOffset:instanceCount:baseInstance:)``                                                             |``doc://com.apple.metal/documentation/Metal/MTLStages/vertex``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``                                                                       |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/drawPatches(numberOfPatchControlPoints:patchIndexBuffer:patchIndexBufferOffset:indirectBuffer:indirectBufferOffset:)``                                                                          |``doc://com.apple.metal/documentation/Metal/MTLStages/vertex``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``                                                                       |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/drawIndexedPatches(numberOfPatchControlPoints:patchStart:patchCount:patchIndexBuffer:patchIndexBufferOffset:controlPointIndexBuffer:controlPointIndexBufferOffset:instanceCount:baseInstance:)``|``doc://com.apple.metal/documentation/Metal/MTLStages/vertex``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``                                                                       |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/drawIndexedPatches(numberOfPatchControlPoints:patchIndexBuffer:patchIndexBufferOffset:controlPointIndexBuffer:controlPointIndexBufferOffset:indirectBuffer:indirectBufferOffset:)``             |``doc://com.apple.metal/documentation/Metal/MTLStages/vertex``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``                                                                       |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/dispatchThreadsPerTile(_:)``                                                                                                                                                                    |``doc://com.apple.metal/documentation/Metal/MTLStages/tile``                                                                                                                                                    |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/executeCommandsInBuffer(_:range:)``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/executeCommandsInBuffer:withRange:``                                          |None                                                                                                                                                                                                            |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/executeCommandsInBuffer(_:indirectBuffer:offset:)``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/executeCommandsInBuffer:indirectBuffer:indirectBufferOffset:``|None                                                                                                                                                                                                            |
|``doc://com.apple.metal/documentation/Metal/MTLRenderCommandEncoder/sampleCounters(sampleBuffer:sampleIndex:barrier:)``                                                                                                                                             |None                                                                                                                                                                                                            |

Draw commands don’t apply to [`fragment`](/documentation/Metal/MTLStages/fragment) when the [`MTLRenderPipelineState`](/documentation/Metal/MTLRenderPipelineState) for the draw disables rasterization.
See [`isRasterizationEnabled`](/documentation/Metal/MTLRenderPipelineDescriptor/isRasterizationEnabled).

Mesh draw commands don’t apply to [`object`](/documentation/Metal/MTLStages/object) when the [`MTLRenderPipelineState`](/documentation/Metal/MTLRenderPipelineState) for the draw doesn’t have an object shader.

The [`executeCommandsInBuffer(_:range:)`](/documentation/Metal/MTLRenderCommandEncoder/executeCommandsInBuffer(_:range:)) and [`executeCommandsInBuffer(_:indirectBuffer:offset:)`](/documentation/Metal/MTLRenderCommandEncoder/executeCommandsInBuffer(_:indirectBuffer:offset:)) commands don’t apply to any stage,
which means you can’t use a barrier to wait for all commands in an indirect command buffer to complete.
However, each command within the [`MTLIndirectCommandBuffer`](/documentation/Metal/MTLIndirectCommandBuffer) applies to the same stages as when you encode the equivalent command directly.

> Note: ``doc://com.apple.metal/documentation/Metal/MTLRenderStages`` and its values have the same functionality as ``doc://com.apple.metal/documentation/Metal/MTLStages`` and its corresponding stage values.

For more information about stages and synchronization, see [`MTLStages`](/documentation/Metal/MTLStages) and [Resource synchronization](/documentation/Metal/resource-synchronization).

## Topics

### Configuration commands

Manage the render pass’s overall state.

[Render pass configuration](/documentation/Metal/render-pass-configuration)

Set a render pass’s pipeline state, attachment actions, viewports, and so on, that affect subsequent drawing commands.

### Resource preparation commands

Load buffers, textures, and other resources into GPU memory for each shader type, including mesh, object, vertex, fragment, and tile shaders.

[Mesh and object shader resource preparation commands](/documentation/Metal/mesh-and-object-shader-resource-preparation-commands)

Assign resources to mesh and object shaders, including buffers, textures, acceleration structures, sampler states, and function tables.

[Vertex shader resource preparation commands](/documentation/Metal/vertex-shader-resource-preparation-commands)

Assign resources to vertex shaders, including buffers, textures, acceleration structures, sampler states, and function tables.

[Fragment shader resource preparation commands](/documentation/Metal/fragment-shader-resource-preparation-commands)

Assign resources to fragment shaders, including buffers, textures, acceleration structures, sampler states, and function tables.

[Tile shaders resource preparation commands](/documentation/Metal/tile-shaders-resource-preparation-commands)

Assign resources to tile shaders, including buffers, textures, acceleration structures, sampler states, and function tables.

[Argument buffer resource preparation commands](/documentation/Metal/argument-buffer-resource-preparation-commands)

Load individual resources and multiple resources within a heap into GPU memory so that they’re available to shaders through argument buffers.

### Drawing with vertices

Render primitives with vertex shaders.

[`drawPrimitives(type:vertexStart:vertexCount:)`](/documentation/Metal/MTLRenderCommandEncoder/drawPrimitives(type:vertexStart:vertexCount:))

Encodes a draw command that renders an instance of a geometric primitive.

[`drawPrimitives(type:vertexStart:vertexCount:instanceCount:)`](/documentation/Metal/MTLRenderCommandEncoder/drawPrimitives(type:vertexStart:vertexCount:instanceCount:))

Encodes a draw command that renders multiple instances of a geometric primitive.

[`drawPrimitives(type:vertexStart:vertexCount:instanceCount:baseInstance:)`](/documentation/Metal/MTLRenderCommandEncoder/drawPrimitives(type:vertexStart:vertexCount:instanceCount:baseInstance:))

Encodes a draw command that renders multiple instances of a geometric primitive that starts with a custom instance identification number.

[`drawPrimitives(type:indirectBuffer:indirectBufferOffset:)`](/documentation/Metal/MTLRenderCommandEncoder/drawPrimitives(type:indirectBuffer:indirectBufferOffset:))

Encodes a draw command that renders multiple instances of a geometric primitive with indirect arguments.

### Drawing with indexed vertices

Render indexed primitives with vertex shaders.

[`drawIndexedPrimitives(type:indexCount:indexType:indexBuffer:indexBufferOffset:)`](/documentation/Metal/MTLRenderCommandEncoder/drawIndexedPrimitives(type:indexCount:indexType:indexBuffer:indexBufferOffset:))

Encodes a draw command that renders an instance of a geometric primitive with indexed vertices.

[`drawIndexedPrimitives(type:indexCount:indexType:indexBuffer:indexBufferOffset:instanceCount:)`](/documentation/Metal/MTLRenderCommandEncoder/drawIndexedPrimitives(type:indexCount:indexType:indexBuffer:indexBufferOffset:instanceCount:))

Encodes a draw command that renders multiple instances of a geometric primitive with indexed vertices.

[`drawIndexedPrimitives(type:indexCount:indexType:indexBuffer:indexBufferOffset:instanceCount:baseVertex:baseInstance:)`](/documentation/Metal/MTLRenderCommandEncoder/drawIndexedPrimitives(type:indexCount:indexType:indexBuffer:indexBufferOffset:instanceCount:baseVertex:baseInstance:))

Encodes a draw command that renders multiple instances of a geometric primitive with indexed vertices, starting with a custom vertex and instance.

[`drawIndexedPrimitives(type:indexType:indexBuffer:indexBufferOffset:indirectBuffer:indirectBufferOffset:)`](/documentation/Metal/MTLRenderCommandEncoder/drawIndexedPrimitives(type:indexType:indexBuffer:indexBufferOffset:indirectBuffer:indirectBufferOffset:))

Encodes a draw command that renders multiple instances of a geometric primitive with indexed vertices and indirect arguments.

### Drawing with meshes

Render meshes with mesh and object shaders.

[`drawMeshThreads(_:threadsPerObjectThreadgroup:threadsPerMeshThreadgroup:)`](/documentation/Metal/MTLRenderCommandEncoder/drawMeshThreads(_:threadsPerObjectThreadgroup:threadsPerMeshThreadgroup:))

Encodes a draw command that invokes a mesh shader and, optionally, an object shader with a grid of threads.

[`drawMeshThreadgroups(_:threadsPerObjectThreadgroup:threadsPerMeshThreadgroup:)`](/documentation/Metal/MTLRenderCommandEncoder/drawMeshThreadgroups(_:threadsPerObjectThreadgroup:threadsPerMeshThreadgroup:))

Encodes a draw command that invokes a mesh shader and, optionally, an object shader with a grid of threadgroups.

[`drawMeshThreadgroups(indirectBuffer:indirectBufferOffset:threadsPerObjectThreadgroup:threadsPerMeshThreadgroup:)`](/documentation/Metal/MTLRenderCommandEncoder/drawMeshThreadgroups(indirectBuffer:indirectBufferOffset:threadsPerObjectThreadgroup:threadsPerMeshThreadgroup:))

Encodes a draw command that invokes a mesh shader and, optionally, an object shader with indirect arguments.

### Drawing with tessellation patches

Render tessellated geometry with control points.

[`drawPatches(numberOfPatchControlPoints:patchStart:patchCount:patchIndexBuffer:patchIndexBufferOffset:instanceCount:baseInstance:)`](/documentation/Metal/MTLRenderCommandEncoder/drawPatches(numberOfPatchControlPoints:patchStart:patchCount:patchIndexBuffer:patchIndexBufferOffset:instanceCount:baseInstance:))

Encodes a draw command that renders multiple instances of tessellated patches.

[`drawPatches(numberOfPatchControlPoints:patchIndexBuffer:patchIndexBufferOffset:indirectBuffer:indirectBufferOffset:)`](/documentation/Metal/MTLRenderCommandEncoder/drawPatches(numberOfPatchControlPoints:patchIndexBuffer:patchIndexBufferOffset:indirectBuffer:indirectBufferOffset:))

Encodes a draw command that renders multiple instances of tessellated patches with indirect arguments.

### Drawing with indexed tessellation patches

Render tessellated geometry with indexed control points.

[`drawIndexedPatches(numberOfPatchControlPoints:patchStart:patchCount:patchIndexBuffer:patchIndexBufferOffset:controlPointIndexBuffer:controlPointIndexBufferOffset:instanceCount:baseInstance:)`](/documentation/Metal/MTLRenderCommandEncoder/drawIndexedPatches(numberOfPatchControlPoints:patchStart:patchCount:patchIndexBuffer:patchIndexBufferOffset:controlPointIndexBuffer:controlPointIndexBufferOffset:instanceCount:baseInstance:))

Encodes a draw command that renders multiple instances of tessellated patches with a control point index buffer.

[`drawIndexedPatches(numberOfPatchControlPoints:patchIndexBuffer:patchIndexBufferOffset:controlPointIndexBuffer:controlPointIndexBufferOffset:indirectBuffer:indirectBufferOffset:)`](/documentation/Metal/MTLRenderCommandEncoder/drawIndexedPatches(numberOfPatchControlPoints:patchIndexBuffer:patchIndexBufferOffset:controlPointIndexBuffer:controlPointIndexBufferOffset:indirectBuffer:indirectBufferOffset:))

Encodes a draw command that renders multiple instances of tessellated patches with a control point index buffer and indirect arguments.

### Drawing with tile shaders

Dispatch tile shaders within a render pass.

[`dispatchThreadsPerTile(_:)`](/documentation/Metal/MTLRenderCommandEncoder/dispatchThreadsPerTile(_:))

Encodes a command that invokes GPU functions from the encoder’s current tile render pipeline state.

[`tileWidth`](/documentation/Metal/MTLRenderCommandEncoder/tileWidth)

The width of the tiles, in pixels, for the render command encoder.

[`tileHeight`](/documentation/Metal/MTLRenderCommandEncoder/tileHeight)

The height of the tiles, in pixels, for the render command encoder.

### Preventing resource access conflicts

Address hazards for untracked resources with fences and barriers.

[`waitForFence(_:before:)`](/documentation/Metal/MTLRenderCommandEncoder/waitForFence(_:before:))

Encodes a command that instructs the GPU to pause before starting one or more stages of the render pass until a pass updates a fence.

[`updateFence(_:after:)`](/documentation/Metal/MTLRenderCommandEncoder/updateFence(_:after:))

Encodes a command that instructs the GPU to update a fence after one or more stages,
which can unblock other passes waiting for the fence.

[`memoryBarrier(resources:after:before:)`](/documentation/Metal/MTLRenderCommandEncoder/memoryBarrier(resources:after:before:))

Creates a memory barrier that enforces the order of write and read operations for specific resources.

[`memoryBarrierWithResources:count:afterStages:beforeStages:`](/documentation/Metal/MTLRenderCommandEncoder/memoryBarrierWithResources:count:afterStages:beforeStages:)

Creates a memory barrier that enforces the order of write and read operations for specific resources.

[`memoryBarrier(scope:after:before:)`](/documentation/Metal/MTLRenderCommandEncoder/memoryBarrier(scope:after:before:))

Creates a memory barrier that enforces the order of write and read operations for specific resource types.

### Running commands from indirect command buffers

Invoke commands within an indirect command buffer.

[`executeCommandsInBuffer(_:range:)`](/documentation/Metal/MTLRenderCommandEncoder/executeCommandsInBuffer(_:range:))

Encodes a command that runs a range of commands from an indirect command buffer (ICB).

[`executeCommandsInBuffer(_:indirectBuffer:offset:)`](/documentation/Metal/MTLRenderCommandEncoder/executeCommandsInBuffer(_:indirectBuffer:offset:))

Encodes a command that runs an indirect range of commands from an indirect command buffer (ICB).

[`executeCommandsInBuffer:withRange:`](/documentation/Metal/MTLRenderCommandEncoder/executeCommandsInBuffer:withRange:)

Encodes a command that runs a range of commands from an indirect command buffer (ICB).

[`executeCommandsInBuffer:indirectBuffer:indirectBufferOffset:`](/documentation/Metal/MTLRenderCommandEncoder/executeCommandsInBuffer:indirectBuffer:indirectBufferOffset:)

Encodes a command that runs an indirect range of commands from an indirect command buffer (ICB).

### Sampling counters

Capture runtime data from GPU hardware counters.

[`sampleCounters(sampleBuffer:sampleIndex:barrier:)`](/documentation/Metal/MTLRenderCommandEncoder/sampleCounters(sampleBuffer:sampleIndex:barrier:))

Encodes a command that samples hardware counters during the render pass and stores the data into a counter sample buffer.

### Deprecated

Replace older symbols in this group with their newer equivalents.

[Deprecated symbols](/documentation/Metal/deprecated-symbols)

Review unsupported symbols and their replacements.



---

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)
