start working out field bind type info
This commit is contained in:
parent
65284fcacb
commit
ba1f48f743
@ -41,13 +41,6 @@ struct UniformAttributeArgs {
|
|||||||
pub shader_def: Option<bool>,
|
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))]
|
#[proc_macro_derive(Uniforms, attributes(uniform))]
|
||||||
pub fn derive_uniforms(input: TokenStream) -> TokenStream {
|
pub fn derive_uniforms(input: TokenStream) -> TokenStream {
|
||||||
const UNIFORM_ATTRIBUTE_NAME: &'static str = "uniform";
|
const UNIFORM_ATTRIBUTE_NAME: &'static str = "uniform";
|
||||||
@ -122,108 +115,47 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
|
|||||||
&field.ident
|
&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 field_uniform_names = active_uniform_field_name_strings.iter().map(|f| {
|
||||||
let texture = format!("{}_texture", name);
|
let uniform = format!("{}_{}", struct_name, f);
|
||||||
let sampler = format!("{}_sampler", name);
|
let texture = format!("{}_texture", uniform);
|
||||||
quote!(FieldUniformName {
|
let sampler = format!("{}_sampler", uniform);
|
||||||
field: #name,
|
quote!(bevy::render::render_graph::FieldUniformName {
|
||||||
uniform: #name,
|
field: #f,
|
||||||
|
uniform: #uniform,
|
||||||
texture: #texture,
|
texture: #texture,
|
||||||
sampler: #sampler,
|
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 {
|
let x = quote! {
|
||||||
name: #sampler_name,
|
const #field_uniform_names_ident: &[bevy::render::render_graph::FieldUniformName] = &[
|
||||||
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] = &[
|
|
||||||
#(#field_uniform_names,)*
|
#(#field_uniform_names,)*
|
||||||
];
|
];
|
||||||
|
|
||||||
impl bevy::render::render_graph::AsUniforms for #struct_name {
|
impl bevy::render::render_graph::AsUniforms for #struct_name {
|
||||||
// TODO: max this an iterator that feeds on field_uniform_names_ident
|
// TODO: max this an iterator that feeds on field_uniform_names_ident
|
||||||
fn get_uniform_infos(&self) -> &[bevy::render::render_graph::UniformInfo] {
|
fn get_uniform_infos(&self) -> &[bevy::render::render_graph::FieldUniformName] {
|
||||||
#info_ident
|
#field_uniform_names_ident
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_field_bind_type(&self, name: &str) -> bevy::render::render_graph::FieldBindType {
|
fn get_field_bind_type(&self, name: &str) -> Option<bevy::render::render_graph::FieldBindType> {
|
||||||
#(#field_names => #get_uniform_bytes_field_name,)*
|
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
|
// TODO: Fix this so uniform_name_uniform_info lines up with getbytes
|
||||||
fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>> {
|
fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>> {
|
||||||
use bevy::core::bytes::GetBytes;
|
use bevy::core::bytes::GetBytes;
|
||||||
match name {
|
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,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -242,7 +174,9 @@ uniform-provider
|
|||||||
.collect::<Vec<String>>())
|
.collect::<Vec<String>>())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
};
|
||||||
|
eprintln!("{}", x.to_string());
|
||||||
|
TokenStream::from(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_derive(RegisterAppPlugin)]
|
#[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 legion::prelude::Entity;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
// TODO: add ability to specify specific pipeline for uniforms
|
// TODO: add ability to specify specific pipeline for uniforms
|
||||||
pub trait AsUniforms {
|
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_uniform_bytes(&self, name: &str) -> Option<Vec<u8>>;
|
||||||
fn get_shader_defs(&self) -> Option<Vec<String>>;
|
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
|
// TODO: support zero-copy uniforms
|
||||||
// fn get_uniform_bytes_ref(&self, name: &str) -> Option<&[u8]>;
|
// fn get_uniform_bytes_ref(&self, name: &str) -> Option<&[u8]>;
|
||||||
}
|
}
|
||||||
@ -30,6 +30,75 @@ pub enum FieldBindType {
|
|||||||
Texture,
|
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 {
|
pub trait AsFieldBindType {
|
||||||
fn get_field_uniform_type(&self) -> FieldBindType;
|
fn get_field_uniform_type(&self) -> FieldBindType;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user