1use std::convert::TryFrom as _;
2
3extern crate proc_macro;
4
5mod binding_flags;
6mod descriptors;
7mod format;
8mod graphics_pipeline;
9mod layout;
10mod pass;
11mod pipeline;
12mod pipeline_stages;
13mod repr;
14mod shader_stage;
15mod swizzle;
16
17#[proc_macro_derive(Descriptors, attributes(sierra))]
18pub fn descriptors(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
19 descriptors::descriptors(item).into()
20}
21
22#[proc_macro_derive(ShaderRepr, attributes(sierra))]
23pub fn shader_repr(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
24 repr::shader_repr(item).into()
25}
26
27#[proc_macro_derive(PipelineInput, attributes(sierra))]
28pub fn pipeline_input(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
29 pipeline::pipeline_input(item).into()
30}
31
32#[proc_macro_derive(Pass, attributes(sierra))]
33pub fn render_pass(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
34 pass::pass(item).into()
35}
36
37#[proc_macro]
38pub fn graphics_pipeline_desc(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
39 graphics_pipeline::graphics_pipeline_desc(item).into()
40}
41
42#[proc_macro]
43pub fn shader_stages(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
44 shader_stage::shader_stages(tokens).into()
45}
46
47#[proc_macro]
48pub fn binding_flags(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
49 binding_flags::binding_flags(tokens).into()
50}
51
52#[proc_macro]
53pub fn pipeline_stages(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
54 pipeline_stages::pipeline_stages(tokens).into()
55}
56
57#[proc_macro]
58pub fn swizzle(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
59 swizzle::swizzle(item).into()
60}
61
62#[proc_macro]
63pub fn format(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
64 format::format(item).into()
65}
66
67fn validate_member(member: &syn::Member, item_struct: &syn::ItemStruct) -> syn::Result<u32> {
68 match (member, &item_struct.fields) {
69 (syn::Member::Named(member_ident), syn::Fields::Named(fields)) => {
70 for (index, field) in fields.named.iter().enumerate() {
71 let field_ident = field.ident.as_ref().unwrap();
72 if *field_ident == *member_ident {
73 return u32::try_from(index)
74 .map_err(|_| syn::Error::new_spanned(member, "Too many fields"));
75 }
76 }
77 Err(syn::Error::new_spanned(
78 member,
79 "Member not found in structure",
80 ))
81 }
82 (syn::Member::Unnamed(unnamed), syn::Fields::Unnamed(fields)) => {
83 let valid =
84 usize::try_from(unnamed.index).map_or(false, |index| index < fields.unnamed.len());
85 if !valid {
86 Err(syn::Error::new_spanned(
87 member,
88 "Member index is out of bounds",
89 ))
90 } else {
91 Ok(unnamed.index)
92 }
93 }
94 (syn::Member::Named(named), syn::Fields::Unnamed(_)) => Err(syn::Error::new_spanned(
95 named,
96 "Unexpected unnamed member for tuple-struct",
97 )),
98 (syn::Member::Unnamed(unnamed), syn::Fields::Named(_)) => Err(syn::Error::new_spanned(
99 unnamed,
100 "Unexpected named member for struct",
101 )),
102 (member, syn::Fields::Unit) => Err(syn::Error::new_spanned(
103 member,
104 "Unexpected member reference for unit-struct",
105 )),
106 }
107}
108
109mod kw {
128 proc_easy::easy_token!(acceleration_structure);
129 proc_easy::easy_token!(buffer);
130 proc_easy::easy_token!(image);
131 proc_easy::easy_token!(sampled);
132 proc_easy::easy_token!(sampler);
133 proc_easy::easy_token!(uniform);
134 proc_easy::easy_token!(storage);
135 proc_easy::easy_token!(texel);
136 proc_easy::easy_token!(subpass);
137 proc_easy::easy_token!(color);
138 proc_easy::easy_token!(depth);
139 proc_easy::easy_token!(clear);
140 proc_easy::easy_token!(load);
141 proc_easy::easy_token!(store);
142 proc_easy::easy_token!(capacity);
143 proc_easy::easy_token!(set);
144 proc_easy::easy_token!(push);
145 proc_easy::easy_token!(layout);
146 proc_easy::easy_token!(attachment);
147 proc_easy::easy_token!(top_of_pipe);
148 proc_easy::easy_token!(draw_indirect);
149 proc_easy::easy_token!(vertex_input);
150 proc_easy::easy_token!(vertex_shader);
151 proc_easy::easy_token!(tessellation_control_shader);
152 proc_easy::easy_token!(tessellation_evaluation_shader);
153 proc_easy::easy_token!(geometry_shader);
154 proc_easy::easy_token!(early_fragment_tests);
155 proc_easy::easy_token!(fragment_shader);
156 proc_easy::easy_token!(late_fragment_tests);
157 proc_easy::easy_token!(color_attachment_output);
158 proc_easy::easy_token!(compute_shader);
159 proc_easy::easy_token!(transfer);
160 proc_easy::easy_token!(bottom_of_pipe);
161 proc_easy::easy_token!(host);
162 proc_easy::easy_token!(all_graphics);
163 proc_easy::easy_token!(all_commands);
164 proc_easy::easy_token!(ray_tracing_shader);
165 proc_easy::easy_token!(acceleration_structure_build);
166 proc_easy::easy_token!(dependency);
167 proc_easy::easy_token!(external);
168}