Copying data to a private resource
Use a blit command encoder to copy buffer or texture data to a private resource.
Overview
Resources with an MTLStorageMode.private storage mode are accessible only to the GPU. Private resources perform better than shared resources, and you don’t have to explicitly synchronize them the way you do for managed resources.
However, because private resources aren’t accessible to the CPU, you can’t populate them with it. To write data from the CPU to a private resource, you need to first write the data to a shared or managed resource. You can then copy the data from that resource to the private resource.
For more information about resource storage modes, see Setting resource storage modes.
Copying data from a shared buffer to a private buffer
First, create a shared buffer and populate its contents using the makeBuffer(bytes:length:options:) method.
Next, create a private buffer that’s large enough to store your buffer data using the makeBuffer(length:options:) method.
Finally, encode and commit an copy(from:sourceOffset:to:destinationOffset:size:) command. Set the shared buffer as the sourceBuffer parameter. Set the private buffer as the destinationBuffer parameter.
Copying data from a shared buffer to a private texture
Use this implementation to copy texture data from the CPU to a private texture in one operation, without having to synchronize a managed texture.
First, create a shared buffer and populate its contents with your texture data.
Next, create a private texture with a suitable configuration for the texture data.
Finally, encode and commit an copy(from:sourceOffset:sourceBytesPerRow:sourceBytesPerImage:sourceSize:to:destinationSlice:destinationLevel:destinationOrigin:) command. Set the shared buffer as the sourceBuffer parameter. Set the private texture as the destinationTexture parameter.
Copying data from a shared or managed texture to a private texture
First, create a shared texture or for Mac apps, a managed texture. For more information about creating buffers and textures with specific storage modes, see Setting resource storage modes.
Then populate the contents of the source texture using the replace(region:mipmapLevel:withBytes:bytesPerRow:) method.
Next, create a private texture with a suitable configuration for your texture data. If appropriate, reuse the texture descriptor that you configured for the shared or managed texture.
Finally, encode and commit an copy(from:sourceSlice:sourceLevel:sourceOrigin:sourceSize:to:destinationSlice:destinationLevel:destinationOrigin:) command. Set the shared or managed texture as the sourceTexture parameter. Set the private texture as the destinationTexture parameter.
Copying data from a managed texture to a private texture involves two copy operations. For the first operation, Metal synchronizes the managed texture and copies the texture data from CPU-accessible memory to GPU-accessible memory. For the second operation, Metal copies the texture data from the managed texture to the private texture.
Copying data from a private texture to a shared buffer
Use this implementation to copy texture data from the GPU to a shared buffer, without having to synchronize a managed texture.
First, create a private texture.
Next, create a shared buffer that’s large enough to store your texture data.
Next, encode a compute, render, or blit pass to populate the contents of your private texture.
Finally, encode and commit an copy(from:sourceSlice:sourceLevel:sourceOrigin:sourceSize:to:destinationOffset:destinationBytesPerRow:destinationBytesPerImage:) command. Set the private texture as the sourceTexture parameter. Set the shared buffer as the destinationBuffer parameter.