36 releases
0.9.1 | Jun 23, 2021 |
---|---|
0.8.2 | May 9, 2021 |
0.7.0 | Jan 30, 2021 |
0.6.5 | Nov 27, 2020 |
0.1.0 | Dec 27, 2018 |
#792 in Graphics APIs
7,329 downloads per month
Used in 134 crates
(10 directly)
795KB
16K
SLoC
gfx-backend-metal
Metal backend for gfx-rs.
Normalized Coordinates
Render | Depth | Texture |
---|---|---|
Binding Model
Dimensions of the model:
- Shader stage: vs, fs, cs
- Register: buffers, textures, samplers
- Binding: 0..31 buffers, 0..128 textures, 0..16 samplers
Mirroring
TODO
lib.rs
:
Metal backend internals.
Pipeline Layout
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.
Command recording
One-time-submit primary command buffers are recorded "live" into MTLCommandBuffer
.
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 submit
or execute_commands
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.
Memory
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
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. !
Dependencies
~11–21MB
~272K SLoC