#cpu-gpu #graphics #shader

crabslab

专注于GPU计算的Slab分配器(rust-gpu)

19个版本 (4个重大更新)

0.5.1 2024年5月20日
0.4.8 2024年5月14日
0.4.0 2024年2月28日

#70 in 渲染


用于 2 crates

MIT/Apache

1.5MB
964

slabcraft for crabs

是什么

crabslab 是一个专注于在CPU和GPU之间 marshalling 数据的 slab 实现。

请看下面的示例.

为什么是它?

很难以期望的形式将数据放到GPU上。

为了正确 marshalling 您的数据,您必须了解数据底层数据表示的对齐和大小。这通常会出乎您的意料!

另一方面,使用 slab,只需要您的类型可以被写入数组并且可以从数组中读取。

观点

使用 slab 来处理 着色器 要容易得多。

着色器代码可以用 Rust(通过 rust-gpu)编写,这将使您能够在 CPU 和 GPU 代码中使用此 crate。

rust-gpu

这个 crate 是为了与 rust-gpu 一起使用而制作的。具体来说,使用这个 crate,您可以将您的类型打包到 CPU 上的缓冲区中,然后在 GPU 上的 slab 中读取您的类型(在 Rust 中)。

其他 no-std 平台

尽管这个 crate 是针对 rust-gpu 编写的,但它应该可以在其他 no-std 环境中工作。

以及如何

想法很简单 - crabslab 帮助您管理一个连续的 u32 堆(大约以 Vec<u32> 的形式)。类型实现 SlabItem 特性,将类型写入 slab 的索引作为连续的 u32,并且可以对称地读取它们。

crabslab 包含

  • 一些特质
    • Slab
    • GrowableSlab
    • SlabItem
  • 为您的类型提供 SlabItem derive 宏
  • 一些用于处理 slabs 的新结构体
    • Id
    • Array
    • Offset
  • 一个包装实现 GrowableSlab 的辅助结构体 CpuSlab
  • glam 类型推导 SlabItem 的功能

示例

use crabslab::{CpuSlab, Slab, GrowableSlab, SlabItem, Id};
use glam::{Vec3, Vec4};

#[derive(Debug, Default, SlabItem, PartialEq)]
struct Light {
    direction: Vec3,
    color: Vec4,
    inner_cutoff: f32,
    outer_cutoff: f32,
    is_on: bool
}

impl Light {
    fn standard() -> Self {
        Light {
            direction: Vec3::NEG_Z, // pointing down
            color: Vec4::ONE, // white
            inner_cutoff: 0.5,
            outer_cutoff: 2.6,
            is_on: true
        }
    }
}

fn cpu_code() -> (Id<Light>, Vec<u32>) {
    let light = Light::standard();
    // Create a new slab on the CPU-side.
    // Using CpuSlab make `append` unambiguous, as `Vec` has its own `append` function.
    let mut slab = CpuSlab::new(vec![]);
    let id = slab.append(&light);
    (id, slab.into_inner())
}

fn shader_code(light_id: Id<Light>, slab: &[u32]) {
    let light = slab.read(light_id);
    assert_eq!(Light::standard(), light);
}

let (light_id, slab) = cpu_code();
// marshalling your data depends on which GPU library you are using...
shader_code(light_id, &slab);

依赖关系