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

# MTL4RenderCommandEncoder

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

```
protocol MTL4RenderCommandEncoder : MTL4CommandEncoder
```

## 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

Create a render encoder by calling a factory method of an [`MTL4CommandBuffer`](/documentation/Metal/MTL4CommandBuffer) instance,
such as [`makeRenderCommandEncoder(descriptor:options:)`](/documentation/Metal/MTL4CommandBuffer/makeRenderCommandEncoder(descriptor:options:)).

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/MTL4RenderCommandEncoder/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 in the configuration groups below, such as [`setViewport(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setViewport(_:)) for the viewport, [`setScissorRect(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setScissorRect(_:)) for the scissor rectangle, and [`setDepthStencilState(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setDepthStencilState(_:)) for depth and stencil tests.

Bind resources by calling [`setArgumentTable(_:stages:)`](/documentation/Metal/MTL4RenderCommandEncoder/setArgumentTable(_:stages:)) with an [`MTL4ArgumentTable`](/documentation/Metal/MTL4ArgumentTable) instance.
This table contains the buffers, textures, and other resources your shaders depend on.

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/MTL4CommandEncoder/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/MTL4RenderCommandEncoder/drawPrimitives(primitiveType: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/MTL4RenderCommandEncoder/drawPrimitives(primitiveType: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/MTL4RenderCommandEncoder/drawPrimitives(primitiveType: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/MTL4RenderCommandEncoder/drawPrimitives(primitiveType:indirectBuffer:)``                                                                                                     |``doc://com.apple.metal/documentation/Metal/MTLStages/vertex``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``                                                                       |
|``doc://com.apple.metal/documentation/Metal/MTL4RenderCommandEncoder/drawIndexedPrimitives(primitiveType:indexCount:indexType:indexBuffer:indexBufferLength:)``                                                          |``doc://com.apple.metal/documentation/Metal/MTLStages/vertex``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``                                                                       |
|``doc://com.apple.metal/documentation/Metal/MTL4RenderCommandEncoder/drawIndexedPrimitives(primitiveType:indexCount:indexType:indexBuffer:indexBufferLength:instanceCount:)``                                            |``doc://com.apple.metal/documentation/Metal/MTLStages/vertex``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``                                                                       |
|``doc://com.apple.metal/documentation/Metal/MTL4RenderCommandEncoder/drawIndexedPrimitives(primitiveType:indexCount:indexType:indexBuffer:indexBufferLength: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/MTL4RenderCommandEncoder/drawIndexedPrimitives(primitiveType:indexType:indexBuffer:indexBufferLength:indirectBuffer:)``                                                      |``doc://com.apple.metal/documentation/Metal/MTLStages/vertex``![](spacer)``doc://com.apple.metal/documentation/Metal/MTLStages/fragment``                                                                       |
|``doc://com.apple.metal/documentation/Metal/MTL4RenderCommandEncoder/drawMeshThreads(threadsPerGrid: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/MTL4RenderCommandEncoder/drawMeshThreadgroups(threadgroupsPerGrid: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/MTL4RenderCommandEncoder/drawMeshThreadgroups(indirectBuffer: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/MTL4RenderCommandEncoder/dispatchThreadsPerTile(_:)``                                                                                                                        |``doc://com.apple.metal/documentation/Metal/MTLStages/tile``                                                                                                                                                    |
|``doc://com.apple.metal/documentation/Metal/MTL4RenderCommandEncoder/executeCommands(buffer:range:)``![](spacer)``doc://com.apple.metal/documentation/Metal/MTL4RenderCommandEncoder/executeCommandsInBuffer:withRange:``|None                                                                                                                                                                                                            |
|``doc://com.apple.metal/documentation/Metal/MTL4RenderCommandEncoder/executeCommands(buffer:indirectBuffer:)``                                                                                                           |None                                                                                                                                                                                                            |
|``doc://com.apple.metal/documentation/Metal/MTL4RenderCommandEncoder/writeTimestamp(granularity:after:counterHeap:index:)``                                                                                              |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/MTL4RenderPipelineDescriptor/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 [`executeCommands(buffer:range:)`](/documentation/Metal/MTL4RenderCommandEncoder/executeCommands(buffer:range:)) and [`executeCommands(buffer:indirectBuffer:)`](/documentation/Metal/MTL4RenderCommandEncoder/executeCommands(buffer:indirectBuffer:)) 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.

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

## Topics

### Configuring pipeline state

Set the pipeline state for a render pass.

[`setRenderPipelineState(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setRenderPipelineState(_:))

Configures this encoder with a render pipeline state that applies to your subsequent draw commands.

### Configuring the actions for attachments

[`setColorStoreAction(_:index:)`](/documentation/Metal/MTL4RenderCommandEncoder/setColorStoreAction(_:index:))

Configures the store action for a color attachment.

[`setDepthStoreAction(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setDepthStoreAction(_:))

Configures the store action for the depth attachment.

[`setStencilStoreAction(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setStencilStoreAction(_:))

Configures the store action for the stencil attachment.

### Configuring blend behavior

[`setBlendColor(red:green:blue:alpha:)`](/documentation/Metal/MTL4RenderCommandEncoder/setBlendColor(red:green:blue:alpha:))

Configures each pixel component value, including alpha, for the render pipeline’s constant blend color.

[`setColorAttachmentMap(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setColorAttachmentMap(_:))

Sets the mapping from logical shader color output to physical render pass color attachments.

### Configuring rendering behavior

[`setTriangleFillMode(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setTriangleFillMode(_:))

Configures how subsequent draw commands rasterize triangle and triangle strip primitives.

[`setFrontFacing(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setFrontFacing(_:))

Configures the vertex winding order that determines which face of a geometric primitive is the front one.

[`setCullMode(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setCullMode(_:))

Controls whether Metal culls front facing primitives, back facing primitives, or culls no primitives at all.

### Configuring depth and stencil behavior

[`setDepthStencilState(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setDepthStencilState(_:))

Configures this encoder with a depth stencil state that applies to your subsequent draw commands.

[`setDepthBias(_:slopeScale:clamp:)`](/documentation/Metal/MTL4RenderCommandEncoder/setDepthBias(_:slopeScale:clamp:))

Configures the adjustments a render pass applies to depth values from fragment shader functions
by a scaling factor and bias.

[`setDepthClipMode(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setDepthClipMode(_:))

Controls the behavior for fragments outside of the near or far planes.

[`setDepthTestBounds(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setDepthTestBounds(_:))

Configures the range for depth bounds testing.

[`setDepthTestMinBound:maxBound:`](/documentation/Metal/MTL4RenderCommandEncoder/setDepthTestMinBound:maxBound:)

Configures the minimum and maximum bounds for depth bounds testing.

[`setStencilReferenceValue(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setStencilReferenceValue(_:))

Configures this encoder with a reference value for stencil testing.

[`setStencilReferenceValue(front:back:)`](/documentation/Metal/MTL4RenderCommandEncoder/setStencilReferenceValue(front:back:))

Configures the encoder with different stencil test reference values for front-facing and back-facing primitives.

### Configuring viewport and scissor behavior

[`setViewport(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setViewport(_:))

Sets the viewport which that transforms vertices from normalized device coordinates to window coordinates.

[`setViewports(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setViewports(_:))

Sets an array of viewports to transform vertices from normalized device coordinates to window coordinates.

[`setViewports:count:`](/documentation/Metal/MTL4RenderCommandEncoder/setViewports:count:)

Sets an array of viewports to transform vertices from normalized device coordinates to window coordinates.

[`setScissorRect(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setScissorRect(_:))

Sets a scissor rectangle to discard fragments outside a specific area.

[`setScissorRects(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setScissorRects(_:))

Sets an array of scissor rectangles for a fragment scissor test.

[`setScissorRects:count:`](/documentation/Metal/MTL4RenderCommandEncoder/setScissorRects:count:)

Sets an array of scissor rectangles for a fragment scissor test.

### Configuring visibility testing

[`setVisibilityResultMode(_:offset:)`](/documentation/Metal/MTL4RenderCommandEncoder/setVisibilityResultMode(_:offset:))

Configures a visibility test for Metal to run, and the destination for any results it generates.

### Configuring vertex amplification

[`setVertexAmplificationCount(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setVertexAmplificationCount(_:)-85tu1)

Sets the vertex amplification count and its view mapping for each amplification ID.

[`setVertexAmplificationCount(_:)`](/documentation/Metal/MTL4RenderCommandEncoder/setVertexAmplificationCount(_:)-911ja)

Sets the vertex amplification count and its view mapping for each amplification ID.

[`setVertexAmplificationCount:viewMappings:`](/documentation/Metal/MTL4RenderCommandEncoder/setVertexAmplificationCount:viewMappings:)

Sets the vertex amplification count and its view mapping for each amplification ID.

### Configuring persistent threadgroup memory

[`setObjectThreadgroupMemoryLength(_:index:)`](/documentation/Metal/MTL4RenderCommandEncoder/setObjectThreadgroupMemoryLength(_:index:))

Configures the size of a threadgroup memory buffer for a threadgroup argument in the object shader function.

[`setThreadgroupMemoryLength(_:offset:index:)`](/documentation/Metal/MTL4RenderCommandEncoder/setThreadgroupMemoryLength(_:offset:index:))

Configures the size of a threadgroup memory buffer for a threadgroup argument in the fragment and tile shader functions.

### Binding argument tables

Bind argument tables to pipeline stages.

[`setArgumentTable(_:stages:)`](/documentation/Metal/MTL4RenderCommandEncoder/setArgumentTable(_:stages:))

Associates an argument table with a set of render stages.

### Drawing with vertices

Render primitives with vertex shaders.

[`drawPrimitives(primitiveType:vertexStart:vertexCount:)`](/documentation/Metal/MTL4RenderCommandEncoder/drawPrimitives(primitiveType:vertexStart:vertexCount:))

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

[`drawPrimitives(primitiveType:vertexStart:vertexCount:instanceCount:)`](/documentation/Metal/MTL4RenderCommandEncoder/drawPrimitives(primitiveType:vertexStart:vertexCount:instanceCount:))

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

[`drawPrimitives(primitiveType:vertexStart:vertexCount:instanceCount:baseInstance:)`](/documentation/Metal/MTL4RenderCommandEncoder/drawPrimitives(primitiveType:vertexStart:vertexCount:instanceCount:baseInstance:))

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

[`drawPrimitives(primitiveType:indirectBuffer:)`](/documentation/Metal/MTL4RenderCommandEncoder/drawPrimitives(primitiveType:indirectBuffer:))

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(primitiveType:indexCount:indexType:indexBuffer:indexBufferLength:)`](/documentation/Metal/MTL4RenderCommandEncoder/drawIndexedPrimitives(primitiveType:indexCount:indexType:indexBuffer:indexBufferLength:))

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

[`drawIndexedPrimitives(primitiveType:indexCount:indexType:indexBuffer:indexBufferLength:instanceCount:)`](/documentation/Metal/MTL4RenderCommandEncoder/drawIndexedPrimitives(primitiveType:indexCount:indexType:indexBuffer:indexBufferLength:instanceCount:))

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

[`drawIndexedPrimitives(primitiveType:indexCount:indexType:indexBuffer:indexBufferLength:instanceCount:baseVertex:baseInstance:)`](/documentation/Metal/MTL4RenderCommandEncoder/drawIndexedPrimitives(primitiveType:indexCount:indexType:indexBuffer:indexBufferLength: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(primitiveType:indexType:indexBuffer:indexBufferLength:indirectBuffer:)`](/documentation/Metal/MTL4RenderCommandEncoder/drawIndexedPrimitives(primitiveType:indexType:indexBuffer:indexBufferLength:indirectBuffer:))

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(threadsPerGrid:threadsPerObjectThreadgroup:threadsPerMeshThreadgroup:)`](/documentation/Metal/MTL4RenderCommandEncoder/drawMeshThreads(threadsPerGrid:threadsPerObjectThreadgroup:threadsPerMeshThreadgroup:))

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

[`drawMeshThreadgroups(threadgroupsPerGrid:threadsPerObjectThreadgroup:threadsPerMeshThreadgroup:)`](/documentation/Metal/MTL4RenderCommandEncoder/drawMeshThreadgroups(threadgroupsPerGrid:threadsPerObjectThreadgroup:threadsPerMeshThreadgroup:))

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

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

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

### Drawing with tile shaders

Dispatch tile shaders within a render pass.

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

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

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

Sets the width of a tile for this render pass.

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

Sets the height of a tile for this render pass.

### Running commands from indirect command buffers

Invoke commands within an indirect command buffer.

[`executeCommands(buffer:range:)`](/documentation/Metal/MTL4RenderCommandEncoder/executeCommands(buffer:range:))

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

[`executeCommands(buffer:indirectBuffer:)`](/documentation/Metal/MTL4RenderCommandEncoder/executeCommands(buffer:indirectBuffer:))

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

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

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

### Sampling counters

Capture runtime data from GPU hardware counters.

[`writeTimestamp(granularity:after:counterHeap:index:)`](/documentation/Metal/MTL4RenderCommandEncoder/writeTimestamp(granularity:after:counterHeap:index:))

Writes a GPU timestamp into the given [`MTL4CounterHeap`](/documentation/Metal/MTL4CounterHeap) at `index` after `stage` completes.



---

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)