mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 15:14:50 +00:00
start working out field bind type info
This commit is contained in:
parent
65284fcacb
commit
ba1f48f743
2 changed files with 96 additions and 93 deletions
|
@ -41,13 +41,6 @@ struct UniformAttributeArgs {
|
|||
pub shader_def: Option<bool>,
|
||||
}
|
||||
|
||||
struct FieldUniformName {
|
||||
field: &'static str,
|
||||
uniform: &'static str,
|
||||
texture: &'static str,
|
||||
sampler: &'static str,
|
||||
}
|
||||
|
||||
#[proc_macro_derive(Uniforms, attributes(uniform))]
|
||||
pub fn derive_uniforms(input: TokenStream) -> TokenStream {
|
||||
const UNIFORM_ATTRIBUTE_NAME: &'static str = "uniform";
|
||||
|
@ -122,108 +115,47 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
|
|||
&field.ident
|
||||
});
|
||||
|
||||
let active_uniform_field_name_strings = active_uniform_fields.iter().map(|field| {
|
||||
field.ident.as_ref().unwrap().to_string()
|
||||
}).collect::<Vec<String>>();
|
||||
|
||||
let field_uniform_names = active_uniform_fields.iter().map(|f| {
|
||||
let name = f.ident.as_ref().unwrap().to_string();
|
||||
let texture = format!("{}_texture", name);
|
||||
let sampler = format!("{}_sampler", name);
|
||||
quote!(FieldUniformName {
|
||||
field: #name,
|
||||
uniform: #name,
|
||||
|
||||
let field_uniform_names = active_uniform_field_name_strings.iter().map(|f| {
|
||||
let uniform = format!("{}_{}", struct_name, f);
|
||||
let texture = format!("{}_texture", uniform);
|
||||
let sampler = format!("{}_sampler", uniform);
|
||||
quote!(bevy::render::render_graph::FieldUniformName {
|
||||
field: #f,
|
||||
uniform: #uniform,
|
||||
texture: #texture,
|
||||
sampler: #sampler,
|
||||
})
|
||||
});
|
||||
|
||||
let mut uniform_info = Vec::new();
|
||||
let mut uniform_name_uniform_info = Vec::new();
|
||||
for field in active_uniform_fields.iter() {
|
||||
let name = format!("{}_{}", struct_name, field.ident.as_ref().unwrap());
|
||||
if let Type::Path(ref type_path) = field.ty {
|
||||
let field_type_name = type_path.path.get_ident().unwrap().to_string();
|
||||
if field_type_name == "ColorSource" || field_type_name == "Handle<Texture>" {
|
||||
let texture_name = format!("{}_texture", name);
|
||||
let sampler_name = format!("{}_sampler", name);
|
||||
uniform_name_uniform_info.push(texture_name.clone());
|
||||
uniform_name_uniform_info.push(sampler_name.clone());
|
||||
uniform_info.push(quote!(bevy::render::render_graph::UniformInfo {
|
||||
name: #texture_name,
|
||||
bind_type: bevy::render::render_graph::BindType::SampledTexture {
|
||||
multisampled: false,
|
||||
dimension: bevy::render::render_graph::TextureViewDimension::D2,
|
||||
},
|
||||
}));
|
||||
|
||||
uniform_info.push(quote!(bevy::render::render_graph::UniformInfo {
|
||||
name: #sampler_name,
|
||||
bind_type: bevy::render::render_graph::BindType::Sampler,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
uniform_name_uniform_info.push(name.clone());
|
||||
uniform_info.push(quote!(bevy::render::render_graph::UniformInfo {
|
||||
name: #name,
|
||||
bind_type: bevy::render::render_graph::BindType::Uniform {
|
||||
dynamic: false,
|
||||
// TODO: fill this in with properties
|
||||
properties: Vec::new(),
|
||||
},
|
||||
}));
|
||||
};
|
||||
|
||||
/*
|
||||
uniform infos
|
||||
|
||||
x: ColorSource
|
||||
y: Vec4
|
||||
|
||||
|
||||
infos: [
|
||||
"x_color",
|
||||
"x_texture",
|
||||
"x_sampler",
|
||||
"y"
|
||||
]
|
||||
|
||||
field_names = ["x", "y"]
|
||||
|
||||
InfoIter { field_names, index = 0, needs_sampler = false}
|
||||
|
||||
uniform-provider
|
||||
for entity in entities
|
||||
for info in entity.t.get_uniform_info_iter()
|
||||
if info.bind_type == Uniform
|
||||
entity.t.get_bytes()
|
||||
elif info.bind_type == Texture
|
||||
entity.get_texture()
|
||||
|
||||
*/
|
||||
|
||||
TokenStream::from(quote! {
|
||||
const #info_ident: &[bevy::render::render_graph::UniformInfo] = &[
|
||||
#(#uniform_info,)*
|
||||
];
|
||||
|
||||
const #field_uniform_names_ident: &[FieldUniformName] = &[
|
||||
let x = quote! {
|
||||
const #field_uniform_names_ident: &[bevy::render::render_graph::FieldUniformName] = &[
|
||||
#(#field_uniform_names,)*
|
||||
];
|
||||
|
||||
impl bevy::render::render_graph::AsUniforms for #struct_name {
|
||||
// TODO: max this an iterator that feeds on field_uniform_names_ident
|
||||
fn get_uniform_infos(&self) -> &[bevy::render::render_graph::UniformInfo] {
|
||||
#info_ident
|
||||
fn get_uniform_infos(&self) -> &[bevy::render::render_graph::FieldUniformName] {
|
||||
#field_uniform_names_ident
|
||||
}
|
||||
|
||||
fn get_field_bind_type(&self, name: &str) -> bevy::render::render_graph::FieldBindType {
|
||||
#(#field_names => #get_uniform_bytes_field_name,)*
|
||||
fn get_field_bind_type(&self, name: &str) -> Option<bevy::render::render_graph::FieldBindType> {
|
||||
match name {
|
||||
#(#active_uniform_field_name_strings => #active_uniform_field_names.get_field_bind_type(),)*
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Fix this so uniform_name_uniform_info lines up with getbytes
|
||||
fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>> {
|
||||
use bevy::core::bytes::GetBytes;
|
||||
match name {
|
||||
#(#uniform_name_uniform_info => Some(self.#get_uniform_bytes_field_name.get_bytes()),)*
|
||||
// #(#uniform_name_uniform_info => Some(self.#get_uniform_bytes_field_name.get_bytes()),)*
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +174,9 @@ uniform-provider
|
|||
.collect::<Vec<String>>())
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
eprintln!("{}", x.to_string());
|
||||
TokenStream::from(x)
|
||||
}
|
||||
|
||||
#[proc_macro_derive(RegisterAppPlugin)]
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use crate::render::{color::ColorSource, render_graph::BindType};
|
||||
use crate::render::{color::ColorSource, render_graph::{BindType, TextureViewDimension}};
|
||||
use legion::prelude::Entity;
|
||||
use std::collections::HashMap;
|
||||
|
||||
// TODO: add ability to specify specific pipeline for uniforms
|
||||
pub trait AsUniforms {
|
||||
fn get_uniform_infos(&self) -> &[UniformInfo];
|
||||
fn get_uniform_infos(&self) -> &[FieldUniformName];
|
||||
fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>>;
|
||||
fn get_shader_defs(&self) -> Option<Vec<String>>;
|
||||
fn get_field_bind_type(&self, name: &str) -> FieldBindType;
|
||||
fn get_field_bind_type(&self, name: &str) -> Option<FieldBindType>;
|
||||
// TODO: support zero-copy uniforms
|
||||
// fn get_uniform_bytes_ref(&self, name: &str) -> Option<&[u8]>;
|
||||
}
|
||||
|
@ -30,6 +30,75 @@ pub enum FieldBindType {
|
|||
Texture,
|
||||
}
|
||||
|
||||
pub struct UniformInfoIter<'a, T: AsUniforms> {
|
||||
pub field_uniform_names: &'a [FieldUniformName],
|
||||
pub uniforms: &'a T,
|
||||
pub index: usize,
|
||||
pub add_sampler: bool,
|
||||
|
||||
|
||||
}
|
||||
|
||||
impl<'a, T> UniformInfoIter<'a, T> where T: AsUniforms {
|
||||
pub fn new(field_uniform_names: &'a [FieldUniformName], uniforms: &'a T) -> Self {
|
||||
UniformInfoIter {
|
||||
field_uniform_names,
|
||||
uniforms,
|
||||
index: 0,
|
||||
add_sampler: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for UniformInfoIter<'a, T> where T: AsUniforms {
|
||||
type Item = UniformInfo<'a>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.add_sampler {
|
||||
self.add_sampler = false;
|
||||
Some(UniformInfo {
|
||||
name: self.field_uniform_names[self.index - 1].sampler,
|
||||
bind_type: BindType::Sampler,
|
||||
})
|
||||
} else {
|
||||
if self.index == self.field_uniform_names.len() {
|
||||
None
|
||||
} else {
|
||||
let index = self.index;
|
||||
self.index += 1;
|
||||
let field_uniform_name = self.field_uniform_names[index];
|
||||
let bind_type = self.uniforms.get_field_bind_type(field_uniform_name.field).unwrap();
|
||||
Some(match bind_type {
|
||||
FieldBindType::Uniform => UniformInfo {
|
||||
bind_type: BindType::Uniform {
|
||||
dynamic: false,
|
||||
properties: Vec::new(),
|
||||
},
|
||||
name: field_uniform_name.uniform,
|
||||
},
|
||||
FieldBindType::Texture => {
|
||||
self.add_sampler = true;
|
||||
UniformInfo {
|
||||
bind_type: BindType::SampledTexture {
|
||||
dimension: TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
name: field_uniform_name.texture,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub struct FieldUniformName {
|
||||
field: &'static str,
|
||||
uniform: &'static str,
|
||||
texture: &'static str,
|
||||
sampler: &'static str,
|
||||
}
|
||||
|
||||
pub trait AsFieldBindType {
|
||||
fn get_field_uniform_type(&self) -> FieldBindType;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue