Contents

Assigning memory to sparse textures

Use a resource state encoder to allocate and deallocate sparse tiles for a sparse texture.

Overview

A sparse texture has storage only when you explicitly provide it. Every mipmap in the texture is partitioned into tile-sized regions. Each region can be in one of three states:

  • Unmapped — The region has no memory storage.

  • Uninitialized — You’ve mapped a sparse tile to the region, but provided no texture data.

  • Initialized — You’ve mapped a sparse tile and provided texture data.

Initially, all of the texture’s regions are unmapped. To provide data for a region, you ask the GPU to map regions in the texture to sparse tiles on the texture’s heap, and then copy or render data into those regions. When a region no longer needs memory, you unmap the region to free up its memory for future requests.

Map or unmap sparse tiles

To map or unmap sparse tiles, you issue commands to the GPU using a resource state command encoder (MTLResourceStateCommandEncoder). Encode a command for each update, specifying the texture, a slice and mipmap within that texture, and a region inside that mipmap. Specify the region in tile coordinates.

The GPU looks for free sparse tiles on the texture’s heap and assigns them to the texture. Once the mapping process is complete, future requests to read, write, or sample those regions access the assigned tiles. Metal doesn’t initialize the tiles with data, so to ensure that valid data is available, copy or render data into the newly mapped regions before you read or sample from them.

The GPU fulfills mapping requests in the order that you encoded the commands. Within each command, the GPU maps the tiles in a row-major order on a first-come, first-served basis. If the heap runs out of memory, Metal skips any remaining tiles in the request.

To free tiles and make additional memory available to satisfy other requests, encode commands using the MTLSparseTextureMappingMode.unmap mode instead.

Map the tail mipmaps after you create the texture

If you create a complete mipmap chain for your texture, many of the lower-level mipmaps are smaller than the sparse tile size. To save memory, Metal packs all of these smaller mipmaps into one memory allocation, typically one sparse tile. To guarantee that a texture always has some data to sample, you usually want to map the tail mipmaps after you create the texture and keep the tail mapped until you’re ready to release the texture.

To map the tail mipmaps, ask the texture for the first mipmap in the tail and map any region within it. All of the tail mipmaps are mapped.

Similarly, if you unmap the first mipmap in the tail, all of the tail mipmaps are unmapped.

Synchronize access to tile mapping and unmapping

Tile mapping is performed by the GPU, which means that it happens asynchronously at a future point after you commit the command buffer. Don’t change the memory assigned to a texture while the texture’s contents are being read or written. Use fences or events to ensure that these actions don’t overlap.

For more information about synchronizing Metal commands, see Resource synchronization.

See Also

Sparse textures