#vulkan-api #vulkan #graphics

phobos

快速、强大的 Vulkan 抽象库

34 个版本 (9 个重大变更)

0.10.0 2023年7月6日
0.8.0 2023年5月24日
0.5.2 2023年3月26日

#196 in 图形 API

Download history 11/week @ 2024-03-11 2/week @ 2024-03-18 12/week @ 2024-04-01 2/week @ 2024-05-20

每月165次下载
egui-winit-phobos 中使用

Apache-2.0

580KB
11K SLoC

Phobos

build build-samples

Phobos 是一个旨在使创建 Vulkan 应用程序更加容易的 Vulkan 抽象库。它提供了抽象来自动管理常见的 Vulkan 问题,如同步和资源管理。同时,它旨在完全公开 Vulkan API,而不受重大限制。

目前,该项目处于高度 WIP 状态,并不是所有目标都已被完全实现。它与一个使用它的渲染引擎一起开发,因此功能目前按需添加。

Phobos 做了什么?

  • 从单个配置结构初始化所有 Vulkan。
  • 与显示引擎管理每帧同步。
  • GPU 期货,与 Rust 期货完全集成。
    • 更正式地说,为 phobos::Fence<T> 实现了 Future<Output = T>
  • 提供可用于在渲染器中自动同步资源的任务图。
    • 自动图像布局转换。
    • 自动 renderpass 声明。
    • 自动对缓冲区执行内存屏障。
    • 虚拟资源,意味着实际资源仅在记录时绑定到图。这允许通用图在需要时重用。
  • 对 Vulkan 对象的保险包装。
  • 公共 API 中没有 unsafe,除非访问原始 Vulkan 处理。
  • 完全隐藏描述符集。只需将资源直接绑定到命令缓冲区。
  • 自动管道管理。
  • 着色器反射以自动生成管道布局。
    • 适用于 GLSL 和 HLSL。
    • 目前一次只能启用一个。
  • 自动为需要双缓冲的资源执行双缓冲。
  • 用于每帧分配(如统一缓冲区)的线性分配器。
  • 每个队列类型的类型化命令缓冲区。
  • 自动线程安全命令缓冲区记录。
  • 使用 SubmitBatch 工具将提交批量提交到一个 vkQueueSubmit 调用中,并使用信号量进行同步。
  • 自动为您的光线追踪管道创建着色器绑定表。
  • 对象池用于重用栅栏、本地分配器等。
  • 通过 fsr2-sys 包件轻松集成FSR2。

Phobos不做什么?

  • 为您实现渲染器。它只是暴露Vulkan API。
  • 支持移动GPU。Phobos针对桌面GPU进行优化,不努力支持移动GPU。

示例

更多详细示例,请查看 示例 文件夹。

use phobos::prelude::*;

fn main() {
    // Fill out app settings for initialization
    let settings = AppBuilder::new()
        .version((1, 0, 0))
        .name("Phobos example app")
        .validation(true)
        .window(&window) // Your winit window, or some other interface.
        .present_mode(vk::PresentModeKHR::MAILBOX)
        .scratch_size(1024u64)
        .gpu(ph::GPURequirements {
          dedicated: true,
          queues: vec![
            QueueRequest { dedicated: false, queue_type: QueueType::Graphics },
            QueueRequest { dedicated: true, queue_type: QueueType::Transfer },
            QueueRequest { dedicated: true, queue_type: QueueType::Compute }
          ],
          ..Default::default()
        })
            .build();

  // Initialize Vulkan. There are other ways to initialize, for example
  // with a custom allocator, or without a window context. See the core::init module for this 
  // functionality.
  use phobos::prelude::*;
  let (
    instance,
    physical_device,
    surface,
    device
    allocator,
    exec,
    frame,
    Some(debug_messenger)
  ) = WindowedContext::init(&settings)? else {
    panic!("Asked for debug messenger but didn't get one.")
  };

  // Create a new pass graph for rendering. Note how we only do this once, as 
  // we are using virtual resources that do not depend on the frame.
  let swapchain = VirtualResource::image("swapchain");
  let clear_pass = PassBuilder::render("clear")
          .color_attachment(&swapchain,
                            vk::AttachmentLoadOp::CLEAR,
                            // Clear the swapchain to red.
                            Some(vk::ClearColorValue { float32: [1.0, 0.0, 0.0, 1.0] }))?
            .build();
    let present_pass = PassBuilder::present("present", clear_pass.output(&swapchain).unwrap());
    let graph = PassGraph::new()
            .add_pass(clear_pass)?
            .add_pass(present_pass)?
            .build()?;
    // Your event loop goes here
    while event_loop {
      // Wait for a new frame to be available. Once there is one, the provided
      // callback will be called.
      futures::executor::block_on(frame.new_frame(exec.clone(), window, &surface, |mut ifc| {
            // Bind some physical resources to the render graph.
            let mut bindings = PhysicalResourceBindings::new();
            bindings.bind_image("swapchain", &ifc.swapchain_image.as_ref().unwrap());
            let cmd = exec.on_domain::<domain::Graphics, DefaultAllocator>(None, None)?;
            // Record render graph to our command buffer
            graph.record(cmd, &bindings, &mut ifc, None, &mut ()).finish()
      }))?;
    }
}

支持

访问 docs.rs 页面,或打开一个问题。

计划中的功能

  • 暴露更多Vulkan API功能。

依赖项

~14–34MB
~522K SLoC