Metal Best Practices предлагают использовать тройную буферизацию для динамических буферов данных. Но листинг, представленный в документации, и пример Metal по умолчанию, сгенерированный XCode, блокируют каждый кадр, ожидающий, пока GPU завершит свою работу:
- (void)render
{
// Wait until the inflight command buffer has completed its work
dispatch_semaphore_wait(_frameBoundarySemaphore, DISPATCH_TIME_FOREVER);
// TODO: Update dynamic buffers and send them to the GPU here !
__weak dispatch_semaphore_t semaphore = _frameBoundarySemaphore;
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> commandBuffer) {
// GPU work is complete
// Signal the semaphore to start the CPU work
dispatch_semaphore_signal(semaphore);
}];
// CPU work is complete
// Commit the command buffer and start the GPU work
[commandBuffer commit];
}
Так как же тройная буферизация что-то здесь улучшает?