Article

Optimizing Texture Data

Optimize a texture’s data to improve GPU or CPU access.

Overview

By default, Metal attempts to optimize texture data for GPU or CPU access, based on a given texture’s storage mode and its use in your app. However, you can explicitly optimize texture data for either processor, or opt-out of optimization altogether. When texture data is optimized, performance increases for one processor but decreases for the other.

Before optimizing texture data, carefully consider the storage modes and usage options for your textures. For guidance on resource storage modes, see Setting Resource Storage Modes. For guidance on texture usage options, see MTLTextureUsage.

Optimize Texture Data for GPU Access

By default, Metal attempts to optimize texture data for GPU access if it meets any of these conditions:

If you don’t meet any of these conditions, you must optimize your texture data explicitly. After you create your texture and populate its contents, encode and commit an optimizeContentsForGPUAccess: or optimizeContentsForGPUAccess:slice:level: command.

// Texture 1.
id <MTLTexture> _texture1GPUOptimized;

/* Create the texture. 
 * ...
 */
/* Populate the texture's contents. 
 * ...
 */

// Create a command buffer for GPU work.
id <MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];

// Encode a blit command to optimize the texture for GPU Access.
id <MTLBlitCommandEncoder> blitCommandEncoder = [commandBuffer blitCommandEncoder];
[blitCommandEncoder optimizeContentsForGPUAccess:_texture1GPUOptimized];

// End encoding, add a completion handler, and commit the command buffer.
[blitCommandEncoder endEncoding];
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> cb) {
    // Texture 1 is optimized for GPU access.
}];
[commandBuffer commit];

If your texture is part of a drawable that you obtain from a MTKView, set the view's framebufferOnly property to YES to optimize the drawable for GPU access. This property configures the texture exclusively as a render target and displayable resource.

Optimize Texture Data for CPU Access

By default, Metal attempts to optimize texture data for CPU access if it meets both of these conditions:

If you don’t meet both of these conditions, you must optimize your texture data explicitly. After you create your texture and populate its contents, encode and commit an optimizeContentsForCPUAccess: or optimizeContentsForCPUAccess:slice:level: command.

// Texture 2.
id <MTLTexture> _texture2CPUOptimized;

/* Create the texture. 
 * ...
 */
/* Populate the texture's contents. 
 * ...
 */

// Create a command buffer for GPU work.
id <MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];

// Encode a blit command to optimize the texture for CPU Access.
id <MTLBlitCommandEncoder> blitCommandEncoder = [commandBuffer blitCommandEncoder];
[blitCommandEncoder optimizeContentsForCPUAccess:_texture2CPUOptimized];

// End encoding, add a completion handler, and commit the command buffer.
[blitCommandEncoder endEncoding];
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> cb) {
    // Texture 2 is optimized for CPU access.
}];
[commandBuffer commit];

Apply Lossless Compression to a Texture in iOS

Lossless compression is a specific form of GPU optimization that Metal can apply to texture data. Lossless compression reduces a texture’s memory size without discarding any of its data. In iOS devices with GPU family 5, Metal attempts to apply lossless compression to a texture if it meets all of these conditions:

Additionally, if you meet both of the following conditions, you must optimize your texture data explicitly so Metal can apply lossless compression:

For guidance, see Optimize Texture Data for GPU Access.

Opt-out of Texture Data Optimization for GPU Access

In some cases, your texture data may benefit from opting-out of optimization for GPU access, for example, when optimization has regressed your app’s performance (particularly for render target read-backs on the CPU).

First, create a texture descriptor and set its allowGPUOptimizedContents property to NO.

// Create a texture descriptor.
MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
                                                                                             width:512
                                                                                            height:512
                                                                                         mipmapped:NO];
// Opt-out of GPU optimization.
textureDescriptor.allowGPUOptimizedContents = NO;

Then, set the texture descriptor’s storageMode property to MTLStorageModeShared or MTLStorageModeManaged.

// Set the texture descriptor's storage mode to `MTLStorageModeShared` or `MTLStorageModeManaged`.
#if TARGET_OS_IOS || TARGET_OS_TVOS
textureDescriptor.storageMode = MTLStorageModeShared;
#endif
#if TARGET_OS_OSX
textureDescriptor.storageMode = MTLStorageModeManaged;
#endif

Finally, create a texture from the texture descriptor.

// Create a texture from the texture descriptor.
id <MTLTexture> _texture = [_device newTextureWithDescriptor:textureDescriptor];

See Also

Working with Textures

Creating and Sampling Textures

Load image data into a texture and apply it to a quadrangle.

Understanding Color-Renderable Pixel Format Sizes

Know the size limits of pixel formats used by color render targets in iOS and tvOS GPUs.

Improving Filtering Quality and Sampling Performance

Provide multiple levels of detail for your textures by using mipmaps.

Managing Texture Memory

Take direct control of memory allocation for texture data by using sparse textures.

MTLTexture

A resource that holds formatted image data.

MTLTextureDescriptor

An object that you use to configure new Metal texture objects.

MTKTextureLoader

An object that decodes common image formats into Metal textures for use in your app.

MTLSharedTextureHandle

A texture handle that can be shared across process address space boundaries.

MTLPixelFormat

The data formats that describe the organization and characteristics of individual pixels in a texture.