Device
Description
The device in Daxa is essentially a VkDevice
in Vulkan, but it carries much more responsibility.
Creation
Sample
Graphics Queue
As all applications that use daxa will have a GPU with a graphics queue, daxa::Device also represents the graphics queue. This is not a problem regarding the multi-queue as no modern GPU has multiple hardware graphics queues; there is no benefit in having numerous VkQueues of the graphics queue family.
In Daxa, you use the device directly instead of choosing to create and then using a VkQueue for graphics command submission. Example of using the device for submitting commands:
This generally reduces boilerplate and conveniently merges the VkDevice and VkQeueue concepts.
Note that Daxa will support async compute and async transfer queues in the future. As no one has requested these up to this point, Daxa does not implement them.
Aside from submitting commands, daxa::Device is also responsible for presenting frames to a swapchain:
Collecting Garbage
As mentioned in the lifetime section, Daxa defers the destruction of objects until collecting garbage.
This is an essential function. It scans through the array of queued object destructions; it checks if the GPU caught up to the point on the timeline where the resource was “destroyed.” If the GPU catches up, they get destroyed for real; if not, they stay in the queue. It is advised to call it once per frame at the end of the render loop.
Note that collecting garbage is called automatically on device destruction; do not worry about potential leaking here!
This function has another essential caveat! It “locks” the lifetimes of SROs. This means that you may not record commands for this device in parallel to calling collect garbage. This is not a limitation in typical applications.
Note: If fully async command recording is vital, I have plans for “software” command recorders that will work fully parallel with collect garbage, among other features.
Daxa will not error if you try to record commands at the same time as collecting garbage. Instead, it will simply block the thread. Each existing daxa::CommandRecorder holds a read lock on resources, and calling collect garbage will acquire an exclusive write lock.
This is necessary to ensure the efficiency of validation in command recording. Consider this case of Daxa’s internals when recording a command:
By locking the lifetimes on daxa::CommandRecorder creation and unlocking when they get destroyed, we only need to perform two atomic operations per command recorder instead of per recorded command.
Metadata
The device stores all kinds of queriable metadata of the VkPhysicalDevice as well as itself and its SROs.
These can all be queried with device member functions. Here are some examples