diff --git a/ROADMAP.md b/ROADMAP.md index cd0e9296ba..ae424e6a31 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -11,7 +11,7 @@ Here is the current list of planned features. All items are sorted in approximat * Skeletal animation * Macro to produce vertex buffer attributes (and maybe descriptors) from structs * 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 * Custom error type? * Remove as many panics / unwraps as possible diff --git a/bevy_derive/src/lib.rs b/bevy_derive/src/lib.rs index 064fbdd3d2..4e08b8f5f5 100644 --- a/bevy_derive/src/lib.rs +++ b/bevy_derive/src/lib.rs @@ -4,7 +4,7 @@ use darling::FromMeta; use inflector::Inflector; use proc_macro::TokenStream; 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)] 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 .iter() - .filter(|(_field, attrs)| { - match attrs { - Some(attrs) => match attrs.shader_def { - Some(shader_def) => shader_def, - None => false, - }, + .filter(|(_field, attrs)| match attrs { + Some(attrs) => match attrs.shader_def { + Some(shader_def) => shader_def, None => false, - } + }, + None => false, }) .map(|(f, _attr)| *f) .collect::>(); 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_screaming_snake = struct_name.to_string().to_screaming_snake_case(); let info_ident = format_ident!("{}_UNIFORM_INFO", 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 - .iter() - .map(|field| format!("{}_{}", struct_name, field.ident.as_ref().unwrap())) - .collect::>(); - let get_uniform_bytes_field_name = active_uniform_fields.iter().map(|field| &field.ident); - let get_uniform_bytes_uniform_name = uniform_name_uniform_info.clone(); - let get_uniform_info_uniform_name = uniform_name_uniform_info.clone(); + let get_uniform_bytes_field_name = active_uniform_fields.iter().map(|field| { + &field.ident + }); + eprintln!("hitit"); + 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" { + 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, + }, + })); + + uniform_info.push(quote!(bevy::render::render_graph::UniformInfo { + name: #sampler_name, + bind_type: bevy::render::render_graph::BindType::Sampler, + })); + } + } + + 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(), + }, + })); + }; + + let layout_arrays = (0..uniform_info.len()).map(|_| quote!(&[])); let get_uniform_info_array_refs = - (0..active_uniform_fields.len()).map(|i| quote!(&#info_ident[#i])); + (0..uniform_info.len()).map(|i| quote!(&#info_ident[#i])); TokenStream::from(quote! { const #info_ident: &[bevy::render::render_graph::UniformInfo] = &[ - #(bevy::render::render_graph::UniformInfo { - name: #uniform_name_uniform_info, - bind_type: bevy::render::render_graph::BindType::Uniform { - dynamic: false, - // TODO: fill this in with properties - properties: Vec::new(), - }, - },)* + #(#uniform_info,)* ]; 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> { use bevy::core::bytes::GetBytes; 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, } } fn get_uniform_info(&self, name: &str) -> Option<&bevy::render::render_graph::UniformInfo> { match name { - #(#get_uniform_info_uniform_name => Some(#get_uniform_info_array_refs),)* + #(#uniform_name_uniform_info => Some(#get_uniform_info_array_refs),)* _ => None, } } diff --git a/src/render/render_graph/renderers/wgpu_renderer.rs b/src/render/render_graph/renderers/wgpu_renderer.rs index d1c34112fa..4fea168510 100644 --- a/src/render/render_graph/renderers/wgpu_renderer.rs +++ b/src/render/render_graph/renderers/wgpu_renderer.rs @@ -22,7 +22,6 @@ pub struct WgpuRenderer { pub render_pipelines: HashMap, wgpu::RenderPipeline>, pub buffers: HashMap, pub textures: HashMap, - pub textures_from_handles: HashMap, wgpu::TextureView>, pub resource_info: HashMap, pub bind_groups: HashMap, pub bind_group_layouts: HashMap, @@ -63,7 +62,6 @@ impl WgpuRenderer { render_pipelines: HashMap::new(), buffers: HashMap::new(), textures: HashMap::new(), - textures_from_handles: HashMap::new(), resource_info: HashMap::new(), bind_groups: HashMap::new(), bind_group_layouts: HashMap::new(), diff --git a/src/render/render_graph/resource_providers/uniform_resource_provider.rs b/src/render/render_graph/resource_providers/uniform_resource_provider.rs index 6efdf0d31b..5d69521434 100644 --- a/src/render/render_graph/resource_providers/uniform_resource_provider.rs +++ b/src/render/render_graph/resource_providers/uniform_resource_provider.rs @@ -1,7 +1,5 @@ -use crate::{ - render::render_graph::{ - DynamicUniformBufferInfo, AsUniforms, Renderable, Renderer, ResourceProvider, - }, +use crate::render::render_graph::{ + AsUniforms, BindType, DynamicUniformBufferInfo, Renderable, Renderer, ResourceProvider, }; use legion::prelude::*; use std::marker::PhantomData; @@ -52,10 +50,23 @@ where let mut counts = Vec::new(); for (uniforms, _renderable) in query.iter(world) { 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 if self.uniform_buffer_info_names.len() <= 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 .iter() .map(|u| u.get_size())