Skip to content

Commit

Permalink
Rename RustItemKind => RustItemType
Browse files Browse the repository at this point in the history
  • Loading branch information
sytherax committed Jul 28, 2024
1 parent fb8b58b commit 61e6f76
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 70 deletions.
File renamed without changes.
4 changes: 2 additions & 2 deletions wgsl_bindgen/src/generate/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::Ident;

use crate::quote_gen::{rust_type, RustItem, RustItemKind, RustItemPath};
use crate::quote_gen::{rust_type, RustItem, RustItemPath, RustItemType};
use crate::WgslBindgenOption;

pub fn consts_items(invoking_entry_module: &str, module: &naga::Module) -> Vec<RustItem> {
Expand Down Expand Up @@ -34,7 +34,7 @@ pub fn consts_items(invoking_entry_module: &str, module: &naga::Module) -> Vec<R
}?;

Some(RustItem::new(
RustItemKind::ConstVarDecl,
RustItemType::ConstVarDecls.into(),
rust_item_path,
quote! { pub const #name: #type_and_value;},
))
Expand Down
92 changes: 46 additions & 46 deletions wgsl_bindgen/src/generate/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use proc_macro2::{Literal, Span, TokenStream};
use quote::quote;
use syn::{Ident, Index};

use crate::quote_gen::{RustItem, RustItemKind};
use crate::quote_gen::{RustItem, RustItemType};
use crate::wgsl;

fn fragment_target_count(module: &naga::Module, f: &naga::Function) -> usize {
Expand Down Expand Up @@ -165,55 +165,55 @@ fn vertex_input_structs_impls(
) -> Vec<RustItem> {
let vertex_inputs = wgsl::get_vertex_input_structs(invoking_entry_module, module);
vertex_inputs.iter().map(|input| {
let name = Ident::new(&input.item_path.name, Span::call_site());

// Use index to avoid adding prefix to literals.
let count = Index::from(input.fields.len());
let attributes: Vec<_> = input
.fields
.iter()
.map(|(location, m)| {
let field_name: TokenStream = m.name.as_ref().unwrap().parse().unwrap();
let location = Index::from(*location as usize);
let format = wgsl::vertex_format(&module.types[m.ty]);
// TODO: Will the debug implementation always work with the macro?
let format = Ident::new(&format!("{format:?}"), Span::call_site());

quote! {
wgpu::VertexAttribute {
format: wgpu::VertexFormat::#format,
offset: std::mem::offset_of!(Self, #field_name) as u64,
shader_location: #location,
}
let name = Ident::new(&input.item_path.name, Span::call_site());

// Use index to avoid adding prefix to literals.
let count = Index::from(input.fields.len());
let attributes: Vec<_> = input
.fields
.iter()
.map(|(location, m)| {
let field_name: TokenStream = m.name.as_ref().unwrap().parse().unwrap();
let location = Index::from(*location as usize);
let format = wgsl::vertex_format(&module.types[m.ty]);
// TODO: Will the debug implementation always work with the macro?
let format = Ident::new(&format!("{format:?}"), Span::call_site());

quote! {
wgpu::VertexAttribute {
format: wgpu::VertexFormat::#format,
offset: std::mem::offset_of!(Self, #field_name) as u64,
shader_location: #location,
}
})
.collect();


// The vertex_attr_array! macro doesn't account for field alignment.
// Structs with glam::Vec4 and glam::Vec3 fields will not be tightly packed.
// Manually calculate the Rust field offsets to support using bytemuck for vertices.
// This works since we explicitly mark all generated structs as repr(C).
// Assume elements are in Rust arrays or slices, so use size_of for stride.
// TODO: Should this enforce WebGPU alignment requirements for compatibility?
// https://gpuweb.github.io/gpuweb/#abstract-opdef-validating-gpuvertexbufferlayout

// TODO: Support vertex inputs that aren't in a struct.
let ts = quote! {
impl #name {
pub const VERTEX_ATTRIBUTES: [wgpu::VertexAttribute; #count] = [#(#attributes),*];

pub const fn vertex_buffer_layout(step_mode: wgpu::VertexStepMode) -> wgpu::VertexBufferLayout<'static> {
wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<Self>() as u64,
step_mode,
attributes: &Self::VERTEX_ATTRIBUTES
}
}
})
.collect();


// The vertex_attr_array! macro doesn't account for field alignment.
// Structs with glam::Vec4 and glam::Vec3 fields will not be tightly packed.
// Manually calculate the Rust field offsets to support using bytemuck for vertices.
// This works since we explicitly mark all generated structs as repr(C).
// Assume elements are in Rust arrays or slices, so use size_of for stride.
// TODO: Should this enforce WebGPU alignment requirements for compatibility?
// https://gpuweb.github.io/gpuweb/#abstract-opdef-validating-gpuvertexbufferlayout

// TODO: Support vertex inputs that aren't in a struct.
let ts = quote! {
impl #name {
pub const VERTEX_ATTRIBUTES: [wgpu::VertexAttribute; #count] = [#(#attributes),*];

pub const fn vertex_buffer_layout(step_mode: wgpu::VertexStepMode) -> wgpu::VertexBufferLayout<'static> {
wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<Self>() as u64,
step_mode,
attributes: &Self::VERTEX_ATTRIBUTES
}
}
};
}
};

RustItem { kind: RustItemKind::TypeImpls, path: input.item_path.clone(), item: ts }
RustItem { types: RustItemType::TypeImpls.into(), path: input.item_path.clone(), item: ts }
}).collect()
}

Expand Down
24 changes: 16 additions & 8 deletions wgsl_bindgen/src/quote_gen/rust_item.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![allow(dead_code)]
use derive_more::Constructor;
use enumflags2::{bitflags, BitFlags};
use proc_macro2::{Span, TokenStream};
use quote::ToTokens;
use smol_str::SmolStr;
Expand Down Expand Up @@ -30,8 +31,8 @@ impl RustItemPath {
}
}

/// Returns a shortened `TokenStream`,
/// If the module of the item is the same as given `target_module`, it will return just the `name` part of the path.
/// Returns a shortened `TokenStream`,
/// If the module of the item is the same as given `target_module`, it will return just the `name` part of the path.
/// Otherwise, it will return the full path.
pub fn short_token_stream(&self, target_module: &str) -> TokenStream {
if self.module == target_module {
Expand All @@ -43,20 +44,27 @@ impl RustItemPath {
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) enum RustItemKind {
ConstVarDecl,
#[bitflags]
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub(crate) enum RustItemType {
/// like `const VAR_NAME: Type = value;`
ConstVarDecls,

/// like `impl Trait for Struct {}`
TraitImpls,

/// like `impl Struct {}`
TypeImpls,

/// like `struct Struct {}`
TypeDefs,
TypeDefAndImpls,
Any,
}

/// Represents a Rust source item, that is either a ConstVar, TraitImpls or others.
#[derive(Constructor)]
pub(crate) struct RustItem {
pub kind: RustItemKind,
pub types: BitFlags<RustItemType>,
pub path: RustItemPath,
pub item: TokenStream,
}
22 changes: 12 additions & 10 deletions wgsl_bindgen/src/quote_gen/rust_module_builder.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![allow(unused)]

use enumflags2::{BitFlag, BitFlags};
use miette::Diagnostic;
use proc_macro2::TokenStream;
use quote::quote;
Expand All @@ -8,7 +9,7 @@ use syn::Ident;
use thiserror::Error;

use super::constants::MOD_REFERENCE_ROOT;
use super::{RustItem, RustItemKind};
use super::{RustItem, RustItemType};
use crate::quote_gen::constants::mod_reference_root;
use crate::FastIndexMap;

Expand All @@ -24,7 +25,7 @@ pub enum RustModuleBuilderError {

struct UniqueItemInfo {
index: usize,
kind: RustItemKind,
types: BitFlags<RustItemType>,
}

#[derive(Default)]
Expand Down Expand Up @@ -65,16 +66,16 @@ impl RustModule {
fn add_unique(
&mut self,
id: &str,
kind: RustItemKind,
types: BitFlags<RustItemType>,
content: TokenStream,
) -> Result<(), RustModuleBuilderError> {
if let Some((prev_kind, existing_content)) =
self.unique_content_info.get(id).and_then(|info| {
if let Some((previous_info, existing_content)) =
self.unique_content_info.get_mut(id).and_then(|info| {
let content = self.content.get_mut(info.index)?;
Some((info.kind, content))
Some((info, content))
})
{
if prev_kind == kind {
if previous_info.types == types {
let existing = existing_content.to_string();
let received = content.to_string();
if existing != received {
Expand All @@ -86,13 +87,14 @@ impl RustModule {
}
} else {
existing_content.extend(content);
previous_info.types |= types;
}
} else {
self.unique_content_info.insert(
id.to_string(),
UniqueItemInfo {
index: self.content.len(),
kind,
types,
},
);
self.content.push(content);
Expand Down Expand Up @@ -240,7 +242,7 @@ impl RustModBuilder {
let name = item.path.name;

let mut m = self.get_or_create_module(&module_path);
m.add_unique(&name, item.kind, item.item)?;
m.add_unique(&name, item.types, item.item)?;
}

Ok(())
Expand All @@ -258,7 +260,7 @@ impl RustModBuilder {
) -> Result<(), RustModuleBuilderError> {
self
.get_or_create_module(path)
.add_unique(id, RustItemKind::Any, content)
.add_unique(id, RustItemType::all(), content)
}

pub fn merge(mut self, other: Self) -> Self {
Expand Down
8 changes: 4 additions & 4 deletions wgsl_bindgen/src/quote_gen/rust_struct_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use syn::{Ident, Index};

use super::{rust_type, RustItem, RustItemPath, RustTypeInfo};
use crate::bevy_util::demangle_str;
use crate::quote_gen::{RustItemKind, MOD_BYTEMUCK_IMPLS, MOD_STRUCT_ASSERTIONS};
use crate::quote_gen::{RustItemType, MOD_BYTEMUCK_IMPLS, MOD_STRUCT_ASSERTIONS};
use crate::{
sanitized_upper_snake_case, WgslBindgenOption, WgslTypeSerializeStrategy,
WgslTypeVisibility,
Expand Down Expand Up @@ -617,7 +617,7 @@ impl<'a> RustStructBuilder<'a> {

vec![
RustItem::new(
RustItemKind::TypeDefAndImpls,
RustItemType::TypeDefs | RustItemType::TypeImpls,
self.item_path.clone(),
quote! {
#repr_c
Expand All @@ -631,12 +631,12 @@ impl<'a> RustStructBuilder<'a> {
},
),
RustItem::new(
RustItemKind::TypeDefAndImpls,
RustItemType::ConstVarDecls.into(),
RustItemPath::new(MOD_STRUCT_ASSERTIONS.into(), fully_qualified_name.clone()),
assert_layout,
),
RustItem::new(
RustItemKind::TypeDefAndImpls,
RustItemType::TraitImpls.into(),
RustItemPath::new(MOD_BYTEMUCK_IMPLS.into(), fully_qualified_name.clone()),
unsafe_bytemuck_pod_impl,
),
Expand Down

0 comments on commit 61e6f76

Please sign in to comment.