rendy:: util:: metal
In Metal, push constants, vertex buffers, and resources in the descriptor sets are all placed together in the native resource bindings, which work similarly to D3D11: there are tables of textures, buffers, and samplers.
We put push constants first (if any) in the table, followed by descriptor set 0 resource, followed by other descriptor sets. The vertex buffers are bound at the very end of the VS buffer table.
When argument buffers are supported, each descriptor set becomes a buffer binding, but the general placement rule is the same.
One-time-submit primary command buffers are recorded "live" into
Special care is taken to the recording state: active bindings are restored at the
start of any render or compute pass.
Multi-submit and secondary command buffers are recorded as "soft" commands into
Journal. Actual native recording is done at either
correspondingly. When that happens, we
enqueue the command buffer at the start
of recording, which allows the driver to work on pass translation at the same time
as we are recording the following passes.
In general, "Shared" storage is used for CPU-coherent memory. "Managed" is used for non-coherent CPU-visible memory. Finally, "Private" storage is backing device-local memory types.
Metal doesn't have CPU-visible memory for textures. We only allow RGBA8 2D textures to be allocated from it, and only for the matter of transfer operations, which is the minimum required by Vulkan. In fact, these become just glorified staging buffers.
Events are represented by just an atomic bool. When recording, a command buffer keeps track of all events set or reset. Signalling within a command buffer is therefore a matter of simply checking that local list. When making a submission, used events are also accumulated temporarily, so that we can change their values in the completion handler of the last command buffer. We also check this list in order to resolve events fired in one command buffer and waited in another one within the same submission.
Waiting for an event from a different submission is accomplished similar to waiting for the host. We block all the submissions until the host blockers are resolved, and these are checked at certain points like setting an event by the device, or waiting for a fence.
Method of recording one-time-submit command buffers.