start working out how AsUNiforms works with textures

This commit is contained in:
Carter Anderson 2020-02-20 21:52:45 -08:00
parent 4eaae0f815
commit fb61204d53
4 changed files with 77 additions and 36 deletions

View File

@ -11,7 +11,7 @@ Here is the current list of planned features. All items are sorted in approximat
* Skeletal animation * Skeletal animation
* Macro to produce vertex buffer attributes (and maybe descriptors) from structs * Macro to produce vertex buffer attributes (and maybe descriptors) from structs
* Add runtime type safety to uniform bindings (and maybe compile time) * Add runtime type safety to uniform bindings (and maybe compile time)
* Inject layout set/bindings into shader source so they don't need to be defined in-shader * Inject layout set/bindings into shader source so they don't need to be defined in-shader. Specify set / binding indices in resource providers?
* Error Handling * Error Handling
* Custom error type? * Custom error type?
* Remove as many panics / unwraps as possible * Remove as many panics / unwraps as possible

View File

@ -4,7 +4,7 @@ use darling::FromMeta;
use inflector::Inflector; use inflector::Inflector;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::{format_ident, quote}; use quote::{format_ident, quote};
use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Field, Fields}; use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Field, Fields, Type};
#[proc_macro_derive(EntityArchetype)] #[proc_macro_derive(EntityArchetype)]
pub fn derive_entity_archetype(input: TokenStream) -> TokenStream { pub fn derive_entity_archetype(input: TokenStream) -> TokenStream {
@ -86,47 +86,79 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
let shader_def_fields = uniform_fields let shader_def_fields = uniform_fields
.iter() .iter()
.filter(|(_field, attrs)| { .filter(|(_field, attrs)| match attrs {
match attrs {
Some(attrs) => match attrs.shader_def { Some(attrs) => match attrs.shader_def {
Some(shader_def) => shader_def, Some(shader_def) => shader_def,
None => false, None => false,
}, },
None => false, None => false,
}
}) })
.map(|(f, _attr)| *f) .map(|(f, _attr)| *f)
.collect::<Vec<&Field>>(); .collect::<Vec<&Field>>();
let shader_def_field_names = shader_def_fields.iter().map(|field| &field.ident); let shader_def_field_names = shader_def_fields.iter().map(|field| &field.ident);
let shader_def_field_names_screaming_snake = shader_def_fields.iter().map(|field| field.ident.as_ref().unwrap().to_string().to_screaming_snake_case()); let shader_def_field_names_screaming_snake = shader_def_fields.iter().map(|field| {
field
.ident
.as_ref()
.unwrap()
.to_string()
.to_screaming_snake_case()
});
let struct_name = &ast.ident; let struct_name = &ast.ident;
let struct_name_screaming_snake = struct_name.to_string().to_screaming_snake_case(); let struct_name_screaming_snake = struct_name.to_string().to_screaming_snake_case();
let info_ident = format_ident!("{}_UNIFORM_INFO", struct_name_screaming_snake); let info_ident = format_ident!("{}_UNIFORM_INFO", struct_name_screaming_snake);
let layout_ident = format_ident!("{}_UNIFORM_LAYOUTS", struct_name_screaming_snake); let layout_ident = format_ident!("{}_UNIFORM_LAYOUTS", struct_name_screaming_snake);
let layout_arrays = (0..active_uniform_fields.len()).map(|_| quote!(&[]));
let uniform_name_uniform_info = active_uniform_fields let get_uniform_bytes_field_name = active_uniform_fields.iter().map(|field| {
.iter() &field.ident
.map(|field| format!("{}_{}", struct_name, field.ident.as_ref().unwrap())) });
.collect::<Vec<String>>(); eprintln!("hitit");
let get_uniform_bytes_field_name = active_uniform_fields.iter().map(|field| &field.ident); let mut uniform_info = Vec::new();
let get_uniform_bytes_uniform_name = uniform_name_uniform_info.clone(); let mut uniform_name_uniform_info = Vec::new();
let get_uniform_info_uniform_name = uniform_name_uniform_info.clone(); for field in active_uniform_fields.iter() {
let get_uniform_info_array_refs = let name = format!("{}_{}", struct_name, field.ident.as_ref().unwrap());
(0..active_uniform_fields.len()).map(|i| quote!(&#info_ident[#i])); 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>" {
eprintln!("madeit");
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,
},
}));
TokenStream::from(quote! { uniform_info.push(quote!(bevy::render::render_graph::UniformInfo {
const #info_ident: &[bevy::render::render_graph::UniformInfo] = &[ name: #sampler_name,
#(bevy::render::render_graph::UniformInfo { bind_type: bevy::render::render_graph::BindType::Sampler,
name: #uniform_name_uniform_info, }));
}
}
uniform_info.push(quote!(bevy::render::render_graph::UniformInfo {
name: #name,
bind_type: bevy::render::render_graph::BindType::Uniform { bind_type: bevy::render::render_graph::BindType::Uniform {
dynamic: false, dynamic: false,
// TODO: fill this in with properties // TODO: fill this in with properties
properties: Vec::new(), properties: Vec::new(),
}, },
},)* }));
};
let layout_arrays = (0..uniform_info.len()).map(|_| quote!(&[]));
let get_uniform_info_array_refs =
(0..uniform_info.len()).map(|i| quote!(&#info_ident[#i]));
TokenStream::from(quote! {
const #info_ident: &[bevy::render::render_graph::UniformInfo] = &[
#(#uniform_info,)*
]; ];
const #layout_ident: &[&[bevy::render::render_graph::UniformPropertyType]] = &[ const #layout_ident: &[&[bevy::render::render_graph::UniformPropertyType]] = &[
@ -145,13 +177,13 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
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 {
#(#get_uniform_bytes_uniform_name => Some(self.#get_uniform_bytes_field_name.get_bytes()),)* #(#uniform_name_uniform_info => Some(self.#get_uniform_bytes_field_name.get_bytes()),)*
_ => None, _ => None,
} }
} }
fn get_uniform_info(&self, name: &str) -> Option<&bevy::render::render_graph::UniformInfo> { fn get_uniform_info(&self, name: &str) -> Option<&bevy::render::render_graph::UniformInfo> {
match name { match name {
#(#get_uniform_info_uniform_name => Some(#get_uniform_info_array_refs),)* #(#uniform_name_uniform_info => Some(#get_uniform_info_array_refs),)*
_ => None, _ => None,
} }
} }

View File

@ -22,7 +22,6 @@ pub struct WgpuRenderer {
pub render_pipelines: HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>, pub render_pipelines: HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>,
pub buffers: HashMap<String, wgpu::Buffer>, pub buffers: HashMap<String, wgpu::Buffer>,
pub textures: HashMap<String, wgpu::TextureView>, pub textures: HashMap<String, wgpu::TextureView>,
pub textures_from_handles: HashMap<Handle<Texture>, wgpu::TextureView>,
pub resource_info: HashMap<String, ResourceInfo>, pub resource_info: HashMap<String, ResourceInfo>,
pub bind_groups: HashMap<u64, BindGroupInfo>, pub bind_groups: HashMap<u64, BindGroupInfo>,
pub bind_group_layouts: HashMap<u64, wgpu::BindGroupLayout>, pub bind_group_layouts: HashMap<u64, wgpu::BindGroupLayout>,
@ -63,7 +62,6 @@ impl WgpuRenderer {
render_pipelines: HashMap::new(), render_pipelines: HashMap::new(),
buffers: HashMap::new(), buffers: HashMap::new(),
textures: HashMap::new(), textures: HashMap::new(),
textures_from_handles: HashMap::new(),
resource_info: HashMap::new(), resource_info: HashMap::new(),
bind_groups: HashMap::new(), bind_groups: HashMap::new(),
bind_group_layouts: HashMap::new(), bind_group_layouts: HashMap::new(),

View File

@ -1,7 +1,5 @@
use crate::{ use crate::render::render_graph::{
render::render_graph::{ AsUniforms, BindType, DynamicUniformBufferInfo, Renderable, Renderer, ResourceProvider,
DynamicUniformBufferInfo, AsUniforms, Renderable, Renderer, ResourceProvider,
},
}; };
use legion::prelude::*; use legion::prelude::*;
use std::marker::PhantomData; use std::marker::PhantomData;
@ -52,10 +50,23 @@ where
let mut counts = Vec::new(); let mut counts = Vec::new();
for (uniforms, _renderable) in query.iter(world) { for (uniforms, _renderable) in query.iter(world) {
let uniform_layouts = uniforms.get_uniform_layouts(); let uniform_layouts = uniforms.get_uniform_layouts();
for (i, uniform_info) in uniforms.get_uniform_infos().iter().enumerate() { for (i, uniform_info) in uniforms
.get_uniform_infos()
.iter()
.filter(|u| {
if let BindType::Uniform { .. } = u.bind_type {
true
} else {
false
}
})
.enumerate()
{
// only add the first time a uniform info is processed // only add the first time a uniform info is processed
if self.uniform_buffer_info_names.len() <= i { if self.uniform_buffer_info_names.len() <= i {
let uniform_layout = uniform_layouts[i]; let uniform_layout = uniform_layouts[i];
// TODO: size is 0 right now because uniform layout isn't populated
// also size isn't even being used right now?
let size = uniform_layout let size = uniform_layout
.iter() .iter()
.map(|u| u.get_size()) .map(|u| u.get_size())