|
1 | | -# Under construction, not viable for use yet |
| 1 | +# Phobos |
| 2 | + |
| 3 | +Phobos is a fast, powerful Vulkan abstraction library. It provides abstractions to automatically |
| 4 | +manage common Vulkan problems like synchronization and resource management. At the same time, it aims to |
| 5 | +expose the full Vulkan API without major limitations. |
| 6 | + |
| 7 | +At the moment, the project is highly WIP, and not all these goals have been fully achieved yet. It is developed |
| 8 | +together with a rendering engine using it, so features are currently added as needed. |
| 9 | + |
| 10 | +The abstraction level of Phobos sits a bit above [Vulkano](https://crates.io/crates/vulkano). While the full API |
| 11 | +is exposed, Phobos provides many powerful quality-of-life features sitting on top of it (see below) that Vulkano does not implement. |
| 12 | +If you are simply looking for a safe, low-level wrapper around Vulkan, Vulkano is the better choice. |
| 13 | + |
| 14 | +## What does Phobos do? |
| 15 | + |
| 16 | +- All Vulkan initialization from a single configuration structure. |
| 17 | +- Manage per-frame synchronization with the presentation engine. |
| 18 | +- GPU futures, fully integrated with Rust futures. |
| 19 | + - More formally, `Future` is implemented for `phobos::Fence`. |
| 20 | + - There is also a `GpuFuture<T>` which can be used to attach a future value to a fence. |
| 21 | +- Provide a task graph that can be used to automatically synchronize resources in your renderer. |
| 22 | + - Automatic image layout transitions. |
| 23 | + - Automatic renderpass declarations. |
| 24 | + - Automatic memory barriers for buffers. |
| 25 | + - Virtual resources, meaning actual resources are only bound to a graph at record time. This allows general-purpose graphs to be re-used if desired. |
| 26 | +- Safe wrappers for Vulkan objects. |
| 27 | +- Automatic descriptor set management. |
| 28 | +- Automatic pipeline and pipeline layout management. |
| 29 | +- Shader reflection to make binding descriptors easy. |
| 30 | +- A linear allocator for per-frame allocations like uniform buffers. |
| 31 | +- Typed command buffers per queue type. |
| 32 | +- Automatically thread safe command buffer recording. |
| 33 | + |
| 34 | +## What does Phobos not do? |
| 35 | + |
| 36 | +Phobos is not a renderer, it does not implement any visual features. It's intended as a library to help you |
| 37 | +write a Vulkan renderer more easily and correctly, without hiding important API details. |
| 38 | + |
| 39 | +## Example |
| 40 | + |
| 41 | +For more elaborate examples, please check the [examples](examples) folder. |
| 42 | + |
| 43 | +```rust |
| 44 | +use phobos as ph; |
| 45 | + |
| 46 | +fn main() { |
| 47 | + // Fill out app settings for initialization |
| 48 | + let settings = ph::AppBuilder::new() |
| 49 | + .version((1, 0, 0)) |
| 50 | + .name("Phobos example app") |
| 51 | + .validation(true) |
| 52 | + .window(&window) // Your winit window, or some other interface. |
| 53 | + .present_mode(vk::PresentModeKHR::MAILBOX) |
| 54 | + .scratch_size(1024) |
| 55 | + .gpu(ph::GPURequirements { |
| 56 | + dedicated: true, |
| 57 | + queues: vec![ |
| 58 | + ph::QueueRequest { dedicated: false, queue_type: ph::QueueType::Graphics }, |
| 59 | + ph::QueueRequest { dedicated: true, queue_type: ph::QueueType::Transfer }, |
| 60 | + ph::QueueRequest { dedicated: true, queue_type: ph::QueueType::Compute } |
| 61 | + ], |
| 62 | + ..Default::default() |
| 63 | + }) |
| 64 | + .build(); |
| 65 | + |
| 66 | + // Initialize Vulkan. This is generally always going to be the same for every project, but it is |
| 67 | + // not abstracted away to allow keeping each created object separately. |
| 68 | + let instance = ph::VkInstance::new(&settings)?; |
| 69 | + let debug_messenger = ph::DebugMessenger::new(&instance)?; |
| 70 | + let (surface, physical_device) = { |
| 71 | + let mut surface = ph::Surface::new(&instance, &settings)?; |
| 72 | + let physical_device = ph::PhysicalDevice::select(&instance, Some(&surface), &settings)?; |
| 73 | + surface.query_details(&physical_device)?; |
| 74 | + (surface, physical_device) |
| 75 | + }; |
| 76 | + let device = ph::Device::new(&instance, &physical_device, &settings)?; |
| 77 | + let mut alloc = ph::create_allocator(&instance, device.clone(), &physical_device)?; |
| 78 | + let exec = ph::ExecutionManager::new(device.clone(), &physical_device)?; |
| 79 | + let mut frame = { |
| 80 | + let swapchain = ph::Swapchain::new(&instance, device.clone(), &settings, &surface)?; |
| 81 | + ph::FrameManager::new(device.clone(), alloc.clone(), &settings, swapchain)? |
| 82 | + }; |
| 83 | + |
| 84 | + // Create a new pass graph for rendering. Note how we only do this once, as |
| 85 | + // we are using virtual resources that do not depend on the frame. |
| 86 | + let swapchain = ph::VirtualResource::image("swapchain"); |
| 87 | + let clear_pass = ph::PassBuilder::render("clear") |
| 88 | + .color_attachment(swapchain.clone(), vk::AttachmentLoadOp::CLEAR, |
| 89 | + // Clear the swapchain to red. |
| 90 | + Some(vk::ClearColorValue{ float32: [1.0, 0.0, 0.0, 1.0] }))? |
| 91 | + .build(); |
| 92 | + let present_pass = ph::PassBuilder::present("present", clear_pass.output(&swapchain).unwrap()); |
| 93 | + let graph = ph::PassGraph::new() |
| 94 | + .add_pass(clear_pass)? |
| 95 | + .add_pass(present_pass)? |
| 96 | + .build()?; |
| 97 | + // Your event loop goes here |
| 98 | + while event_loop { |
| 99 | + // Wait for a new frame to be available. Once there is one, the provided |
| 100 | + // callback will be called. |
| 101 | + futures::executor::block_on(frame.new_frame(exec.clone(), window, &surface, |mut ifc| { |
| 102 | + // Bind some physical resources to the render graph. |
| 103 | + let mut bindings = ph::PhysicalResourceBindings::new(); |
| 104 | + bindings.bind_image("swapchain", ifc.swapchain_image.as_ref().unwrap().clone()); |
| 105 | + let cmd = exec.on_domain::<ph::domain::Graphics>()?; |
| 106 | + // Record render graph to our command buffer |
| 107 | + ph::record_graph(&mut graph, &bindings, &mut ifc, cmd, None).finish() |
| 108 | + }))?; |
| 109 | + } |
| 110 | +} |
| 111 | +``` |
| 112 | + |
| 113 | +## Support |
| 114 | + |
| 115 | +Visit the [docs.rs](https://docs.rs/phobos/latest) page, or open an issue. |
| 116 | + |
| 117 | +## Planned features |
| 118 | + |
| 119 | +- Compute shader support |
| 120 | +- Raytracing support |
| 121 | +- Automatic semaphore synchronization |
| 122 | +- Expose more Vulkan API features. |
0 commit comments