Skip to content

Commit

Permalink
Add ability to override struct and path based source type
Browse files Browse the repository at this point in the history
  • Loading branch information
syth-trader committed Feb 28, 2024
1 parent a49be89 commit 1d4ee0a
Show file tree
Hide file tree
Showing 34 changed files with 1,011 additions and 787 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ The tool facilitates a shader-focused workflow. When you modify your WGSL shader
## Features
- Supports import syntax and many more features from naga oil flavour.
- BYOT - Bring your own types for wgsl matrix, vectors types. Bindgen automatically also include assertion to test alignment and sizes for your types.
- Override struct types from your crate, which is handy for small primitive types.
- Rust structs for vertex, storage, and uniform buffers
- Generates either new or enum-like short constructors to ease creating the generated types, especially ones that require to be padded when using with bytemuck.
- Final shader source can either as be a single embedded string, or naga_oil with embedded string or instead specified with directory containing the entry source for hot reloading.
- Either use encase or bytemuck derives, and optionally serde for generated structs.
- Const validation of [WGSL memory layout](#memory-layout) for provided vector and matrix types and generated structs when using bytemuck
- More strongly typed [bind group and bindings](#bind-groups) initialization
Expand Down Expand Up @@ -124,7 +126,7 @@ fn main() -> Result<()> {
.add_entry_point("src/shader/testbed.wgsl")
.add_entry_point("src/shader/triangle.wgsl")
.serialization_strategy(WgslTypeSerializeStrategy::Bytemuck)
.wgsl_type_map(GlamWgslTypeMap)
.type_map(GlamWgslTypeMap)
.derive_serde(false)
.output_file("src/shader.rs")
.build()?
Expand Down
2 changes: 1 addition & 1 deletion example/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "example"
version = "0.6.13"
version = "0.7.0"
edition = "2021"

[dependencies]
Expand Down
8 changes: 5 additions & 3 deletions example/build.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
use miette::{IntoDiagnostic, Result};
use wgsl_bindgen::{WgslBindgenOptionBuilder, GlamWgslTypeMap, WgslShaderSourceOutputType, WgslTypeSerializeStrategy};
use wgsl_bindgen::{
GlamWgslTypeMap, WgslBindgenOptionBuilder, WgslShaderSourceType, WgslTypeSerializeStrategy,
};

fn main() -> Result<()> {
WgslBindgenOptionBuilder::default()
.add_entry_point("src/shader/testbed.wgsl")
.add_entry_point("src/shader/triangle.wgsl")
.skip_hash_check(true)
.serialization_strategy(WgslTypeSerializeStrategy::Bytemuck)
.wgsl_type_map(GlamWgslTypeMap)
.type_map(GlamWgslTypeMap)
.derive_serde(false)
.output_file("src/shader.rs")
.short_constructor(2)
.shader_source_output_type(WgslShaderSourceOutputType::Composer)
.shader_source_type(WgslShaderSourceType::UseComposerWithIncludeStr)
.build()?
.generate()
.into_diagnostic()
Expand Down
2 changes: 1 addition & 1 deletion example/src/more-shader-files/reachme.wgsl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
struct RtsStruct {
struct rtsStruct {
other_data: i32,
the_array: array<u32>,
};
Expand Down
41 changes: 12 additions & 29 deletions example/src/shader.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// File automatically generated by wgsl_bindgen^
//
// ^ wgsl_bindgen version 0.6.13
// ^ wgsl_bindgen version 0.7.0
// Changes made to this file will not be saved.
// SourceHash: d47b30b3d426ba56e3bbbe1e92d543437e4b270c4cca19a93ad1862aff8d6d76
// SourceHash: 6f469152513ffb30656f1e8a34dc974a59e090971e235acd89be6ecbd333d8f4

#[allow(unused)]
#![allow(unused, non_snake_case, non_camel_case_types)]
mod _root {
pub use super::*;
const _: () = {
Expand All @@ -19,32 +19,29 @@ mod _root {
};
}
pub mod reachme {
#[allow(unused_imports)]
use super::{_root, _root::*};
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct RtsStruct<const N: usize> {
pub struct rtsStruct<const N: usize> {
/// size: 4, offset: 0x0, type: `i32`
pub other_data: i32,
/// size: 4, offset: 0x4, type: `array<u32>`
pub the_array: [u32; N],
}
#[allow(non_snake_case)]
pub const fn RtsStruct<const N: usize>(
pub const fn rtsStruct<const N: usize>(
other_data: i32,
the_array: [u32; N],
) -> RtsStruct<N> {
RtsStruct { other_data, the_array }
) -> rtsStruct<N> {
rtsStruct { other_data, the_array }
}
unsafe impl<const N: usize> bytemuck::Zeroable for RtsStruct<N> {}
unsafe impl<const N: usize> bytemuck::Pod for RtsStruct<N> {}
unsafe impl<const N: usize> bytemuck::Zeroable for rtsStruct<N> {}
unsafe impl<const N: usize> bytemuck::Pod for rtsStruct<N> {}
const _: () = {
assert!(std::mem::offset_of!(RtsStruct < 1 >, other_data) == 0);
assert!(std::mem::offset_of!(RtsStruct < 1 >, the_array) == 4);
assert!(std::mem::size_of:: < RtsStruct < 1 > > () == 8);
assert!(std::mem::offset_of!(rtsStruct < 1 >, other_data) == 0);
assert!(std::mem::offset_of!(rtsStruct < 1 >, the_array) == 4);
assert!(std::mem::size_of:: < rtsStruct < 1 > > () == 8);
};
}
pub mod types {
#[allow(unused_imports)]
use super::{_root, _root::*};
#[repr(C, align(4))]
#[derive(Debug, PartialEq, Clone, Copy)]
Expand Down Expand Up @@ -398,7 +395,6 @@ pub mod types {
/// size: 48, offset: 0x170, type: `struct`
pub b: _root::types::VectorsF32,
}
#[allow(non_snake_case)]
pub const fn Nested(
a: _root::types::MatricesF32,
b: _root::types::VectorsF32,
Expand All @@ -414,7 +410,6 @@ pub mod types {
};
}
pub mod testbed {
#[allow(unused_imports)]
use super::{_root, _root::*};
#[repr(C, align(16))]
#[derive(Debug, PartialEq, Clone, Copy)]
Expand All @@ -425,7 +420,6 @@ pub mod testbed {
pub scalars: _root::types::Scalars,
pub _pad_scalars: [u8; 0x10 - core::mem::size_of::<_root::types::Scalars>()],
}
#[allow(non_snake_case)]
pub const fn Uniforms(
color_rgb: glam::Vec4,
scalars: _root::types::Scalars,
Expand Down Expand Up @@ -468,7 +462,6 @@ pub mod testbed {
pub struct VertexInput {
pub position: glam::Vec3A,
}
#[allow(non_snake_case)]
pub const fn VertexInput(position: glam::Vec3A) -> VertexInput {
VertexInput { position }
}
Expand All @@ -477,7 +470,6 @@ pub mod testbed {
pub mod bind_groups {
#[derive(Debug)]
pub struct BindGroup0(wgpu::BindGroup);
#[allow(non_snake_case)]
#[derive(Debug)]
pub struct BindGroupLayout0<'a> {
pub color_texture: &'a wgpu::TextureView,
Expand Down Expand Up @@ -547,7 +539,6 @@ pub mod testbed {
}
#[derive(Debug)]
pub struct BindGroup1(wgpu::BindGroup);
#[allow(non_snake_case)]
#[derive(Debug)]
pub struct BindGroupLayout1<'a> {
pub ONE: wgpu::BufferBinding<'a>,
Expand Down Expand Up @@ -615,7 +606,6 @@ pub mod testbed {
}
#[derive(Debug)]
pub struct BindGroup2(wgpu::BindGroup);
#[allow(non_snake_case)]
#[derive(Debug)]
pub struct BindGroupLayout2<'a> {
pub rts: wgpu::BufferBinding<'a>,
Expand Down Expand Up @@ -867,7 +857,6 @@ pub mod testbed {
)
}
pub fn init_composer() -> naga_oil::compose::Composer {
#[allow(unused_mut)]
let mut composer = naga_oil::compose::Composer::default();
composer
.add_composable_module(naga_oil::compose::ComposableModuleDescriptor {
Expand Down Expand Up @@ -927,15 +916,13 @@ pub mod testbed {
}
}
pub mod triangle {
#[allow(unused_imports)]
use super::{_root, _root::*};
#[repr(C, align(16))]
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Uniforms {
/// size: 16, offset: 0x0, type: `vec4<f32>`
pub color_rgb: glam::Vec4,
}
#[allow(non_snake_case)]
pub const fn Uniforms(color_rgb: glam::Vec4) -> Uniforms {
Uniforms { color_rgb }
}
Expand All @@ -950,7 +937,6 @@ pub mod triangle {
pub struct VertexInput {
pub position: glam::Vec3A,
}
#[allow(non_snake_case)]
pub const fn VertexInput(position: glam::Vec3A) -> VertexInput {
VertexInput { position }
}
Expand All @@ -959,7 +945,6 @@ pub mod triangle {
pub mod bind_groups {
#[derive(Debug)]
pub struct BindGroup0(wgpu::BindGroup);
#[allow(non_snake_case)]
#[derive(Debug)]
pub struct BindGroupLayout0<'a> {
pub color_texture: &'a wgpu::TextureView,
Expand Down Expand Up @@ -1029,7 +1014,6 @@ pub mod triangle {
}
#[derive(Debug)]
pub struct BindGroup1(wgpu::BindGroup);
#[allow(non_snake_case)]
#[derive(Debug)]
pub struct BindGroupLayout1<'a> {
pub uniforms: wgpu::BufferBinding<'a>,
Expand Down Expand Up @@ -1155,7 +1139,6 @@ pub mod triangle {
)
}
pub fn init_composer() -> naga_oil::compose::Composer {
#[allow(unused_mut)]
let mut composer = naga_oil::compose::Composer::default();
composer
}
Expand Down
4 changes: 2 additions & 2 deletions example/src/shader/testbed.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

@group(2) @binding(1)
// TODO: Fix this, I think the bug is in naga_oil.
// var<storage> rts: array<reachme::RtsStruct>;
var<storage> rts: reachme::RtsStruct;
// var<storage> rts: array<reachme::rtsStruct>;
var<storage> rts: reachme::rtsStruct;

@group(2) @binding(2)
var<storage> a: Scalars;
Expand Down
4 changes: 3 additions & 1 deletion example/tests/test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, PartialEq, bytemuck::Zeroable, bytemuck::Pod, encase::ShaderType)]
#[derive(
Debug, Default, Copy, Clone, PartialEq, bytemuck::Zeroable, bytemuck::Pod, encase::ShaderType,
)]
pub struct TestStruct {
pub a: f32,
pub b: glam::Vec2, // encase correctly knows this is 8 bytes aligned
Expand Down
3 changes: 1 addition & 2 deletions wgsl_bindgen/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "wgsl_bindgen"
version = "0.6.13"
version = "0.7.0"
authors = ["Swoorup", "ScanMountGoat(Original)"]
description = "Generate typesafe Rust bindings for wgsl shaders in wgpu"
license = "MIT"
Expand Down Expand Up @@ -35,7 +35,6 @@ regex-syntax = "0.8.2"
strum = "0.26.1"
strum_macros = "0.26.1"
pathdiff = "0.2.1"
enum-map = "2.7.3"

[dev-dependencies]
indoc = "2.0"
Expand Down
1 change: 1 addition & 0 deletions wgsl_bindgen/rustfmt.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ tab_spaces = 2
max_width=90
fn_call_width=80
group_imports="StdExternalCrate"
imports_granularity = "Module"
6 changes: 3 additions & 3 deletions wgsl_bindgen/src/bevy_util/deptree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use smallvec::SmallVec;
use thiserror::Error;
use DependencyTreeError::*;

use super::{
parse_imports::ImportStatement, source_file::SourceFile, ModulePathResolver,
};
use super::parse_imports::ImportStatement;
use super::source_file::SourceFile;
use super::ModulePathResolver;
use crate::{
AdditionalScanDirectory, FxIndexMap, FxIndexSet, ImportedPath, SourceFileDir,
SourceFilePath, SourceModuleName,
Expand Down
2 changes: 1 addition & 1 deletion wgsl_bindgen/src/bevy_util/name_demangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub fn escape_os_path(path: &str) -> String {
path.replace("\"", "")
}

/// Converts
/// Converts
/// * "\"../types\"::RtsStruct" => "types::RtsStruct"
/// * "../more-shader-files/reachme" => "reachme"
pub fn make_valid_rust_import(value: &str) -> String {
Expand Down
6 changes: 4 additions & 2 deletions wgsl_bindgen/src/bevy_util/parse_imports.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{ops::Range, sync::OnceLock};
use std::ops::Range;
use std::sync::OnceLock;

use indexmap::IndexMap;
use regex::Regex;
Expand Down Expand Up @@ -230,7 +231,8 @@ mod tests {

#[test]
fn test_parsing_imports_from_bevy_mesh_view_bindings() {
let contents = include_str!("../../tests/shaders/bevy_pbr_wgsl/mesh_view_bindings.wgsl");
let contents =
include_str!("../../tests/shaders/bevy_pbr_wgsl/mesh_view_bindings.wgsl");
let actual = parse_import_statements_iter(contents)
.flat_map(|x| x.get_imported_paths())
.collect::<Vec<_>>();
Expand Down
9 changes: 4 additions & 5 deletions wgsl_bindgen/src/bevy_util/source_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ use smallvec::SmallVec;

use super::parse_imports;
use super::parse_imports::ImportStatement;
use crate::{
types::{FxIndexSet, SourceFilePath},
ImportedPath, SourceModuleName,
};
use crate::types::{FxIndexSet, SourceFilePath};
use crate::{ImportedPath, SourceModuleName};

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SourceFile {
Expand Down Expand Up @@ -63,7 +61,8 @@ mod tests {
let source = SourceFile::create(
source_path,
module_name,
include_str!("../../tests/shaders/bevy_pbr_wgsl/mesh_view_bindings.wgsl").to_owned(),
include_str!("../../tests/shaders/bevy_pbr_wgsl/mesh_view_bindings.wgsl")
.to_owned(),
);
let actual = source.get_imported_paths();

Expand Down
Loading

0 comments on commit 1d4ee0a

Please sign in to comment.