#shader #wgpu #wgsl #proc-macro #graphics #gamedev #compile-time

naga-to-tokenstream

Creates a TokenStream describing parts of a Naga module

10 releases (4 breaking)

0.5.0 Feb 28, 2024
0.4.2 Nov 11, 2023
0.4.0 Oct 27, 2023
0.3.1 Oct 19, 2023
0.1.3 Aug 14, 2023

#546 in Game dev

Download history 8/week @ 2024-01-08 67/week @ 2024-01-15 73/week @ 2024-01-22 22/week @ 2024-01-29 10/week @ 2024-02-05 93/week @ 2024-02-12 36/week @ 2024-02-19 230/week @ 2024-02-26 23/week @ 2024-03-04 43/week @ 2024-03-11 26/week @ 2024-03-18 47/week @ 2024-04-01 5/week @ 2024-04-08 8/week @ 2024-04-15

64 downloads per month
Used in 4 crates (2 directly)

MIT license

35KB
626 lines

Naga to TokenStream

crates.io docs.rs crates.io

This library takes a Naga module and produces a proc_macro::TokenStream giving information about the module. It is intended for use in other libraries which process a shader at compile time, for example in a proc macro or build script, to expose a large collection of useful information to the Rust compiler (and hence programmer) about items in the module.

Generated Items

As an example, take the following shader, written in wgsl:

const ELEMENTS_LENGTH: u32 = 128u;

struct Foo {
    a: i32,
    b: vec4<u32>,
    c: vec4<u32>,
}
struct Bar {
    size: u32,
    elements: array<vec2<bool>, ELEMENTS_LENGTH>,
    foos: array<Foo>
}

@group(0) @binding(0) var<storage> bar: Bar;

@compute
@workgroup_size(256,1,1)
fn main() {
    ...
}

Then this crate would generate something like the following:

/// Equivalent Rust definitions of the constants defined in this module
pub mod constants {
    pub mod ELEMENTS_LENGTH {
        pub const VALUE: u32 = 128;
        pub type Ty = u32;
    }
}
/// Equivalent Rust definitions of the types defined in this module
pub mod types {
    // `encase::ShaderType` is only derived if the `encase` feature is enabled.
    #[derive(Debug, PartialEq, Hash, Clone, encase::ShaderType)] 
    pub struct Foo {
        a: i32,
        // `glam` objects are only generated if the `glam` feature is enabled.
        b: glam::u32::UVec4, 
        c: glam::u32::UVec4,
    }
    #[derive(Debug, PartialEq, Hash, Clone, encase::ShaderType)]
    pub struct Bar {
        size: u32,
        elements: [glam::bool::BVec2; 128],
        #[size(runtime)] // Only added if the `encase` feature is enabled.
        foos: Vec<Foo>,
    }
}
pub mod globals {
    /// Information about the `bar` global variable within the shader module.
    pub mod bar {
        pub const NAME: &'static str = "bar";
        pub type Ty = types::Bar;
        pub mod binding {
            pub const GROUP: u32 = 0u32;
            pub const BINDING: u32 = 0u32;
        }
    }
}
/// Information about the entry points within the module.
pub mod entry_points {
    pub mod main {
        pub const NAME: &'static str = "main";

        /// The sourcecode for the shader, as a constant string, excluding any other entry points. 
        /// This is useful when the `minify` feature is enabled for this crate, as it allows more aggressive 
        /// minification to be performed with the knowledge of the specific entry point that will be used.
        pub const EXCLUSIVE_SOURCE: &'static str = "...";
    }
}
/// The sourcecode for the shader, as a constant string.
pub const SOURCE: &'static str = "...";

Dependencies

~5–13MB
~147K SLoC