diff --git a/crates/bevy_asset/src/assets.rs b/crates/bevy_asset/src/assets.rs index 2eeaedd6b6..0f4ad533c4 100644 --- a/crates/bevy_asset/src/assets.rs +++ b/crates/bevy_asset/src/assets.rs @@ -3,7 +3,6 @@ use crate::{ Handle, HandleId, }; use bevy_app::{AppBuilder, Events, FromResources}; -use bevy_core::bytes::Bytes; use bevy_type_registry::RegisterType; use legion::prelude::*; use std::collections::HashMap; @@ -108,13 +107,6 @@ impl Assets { } } -impl Bytes for Handle { - fn write_bytes(&self, _buffer: &mut [u8]) {} - fn byte_len(&self) -> usize { - 0 - } -} - pub trait AddAsset { fn add_asset(&mut self) -> &mut Self where diff --git a/crates/bevy_core/src/bytes.rs b/crates/bevy_core/src/bytes.rs index 4c2188c13c..91e80788d1 100644 --- a/crates/bevy_core/src/bytes.rs +++ b/crates/bevy_core/src/bytes.rs @@ -1,4 +1,7 @@ use glam::{Mat4, Vec2, Vec3, Vec4}; + +pub use bevy_derive::Bytes; + pub trait Bytes { fn write_bytes(&self, buffer: &mut [u8]); fn byte_len(&self) -> usize; diff --git a/crates/bevy_core/src/lib.rs b/crates/bevy_core/src/lib.rs index 31bd75a430..a9ddc544db 100644 --- a/crates/bevy_core/src/lib.rs +++ b/crates/bevy_core/src/lib.rs @@ -2,8 +2,6 @@ pub mod bytes; pub mod time; pub mod transform; -pub use bevy_derive::Bytes; - use bevy_app::{stage, AppBuilder, AppPlugin}; use bevy_transform::{ components::{ diff --git a/crates/bevy_derive/src/as_vertex_buffer_descriptor.rs b/crates/bevy_derive/src/as_vertex_buffer_descriptor.rs index e5da0a16cc..d10dd03f82 100644 --- a/crates/bevy_derive/src/as_vertex_buffer_descriptor.rs +++ b/crates/bevy_derive/src/as_vertex_buffer_descriptor.rs @@ -1,9 +1,12 @@ -use crate::modules::{get_modules, get_path}; +use crate::{ + attributes::get_field_attributes, + modules::{get_modules, get_path}, +}; 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, Path}; +use syn::{parse_macro_input, DeriveInput, Path}; #[derive(FromMeta, Debug, Default)] struct VertexAttributeArgs { @@ -28,7 +31,7 @@ impl From for VertexAttributes { } } -static UNIFORM_ATTRIBUTE_NAME: &'static str = "uniform"; +static VERTEX_ATTRIBUTE_NAME: &'static str = "vertex"; pub fn derive_as_vertex_buffer_descriptor(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); @@ -36,34 +39,10 @@ pub fn derive_as_vertex_buffer_descriptor(input: TokenStream) -> TokenStream { let bevy_render_path: Path = get_path(&modules.bevy_render); - let fields = match &ast.data { - Data::Struct(DataStruct { - fields: Fields::Named(fields), - .. - }) => &fields.named, - _ => panic!("expected a struct with named fields"), - }; - - let field_attributes = fields - .iter() - .map(|f| { - ( - f, - f.attrs - .iter() - .find(|a| { - a.path.get_ident().as_ref().unwrap().to_string() == UNIFORM_ATTRIBUTE_NAME - }) - .map(|a| { - VertexAttributes::from( - VertexAttributeArgs::from_meta(&a.parse_meta().unwrap()) - .unwrap_or_else(|_err| VertexAttributeArgs::default()), - ) - }) - .unwrap_or_else(|| VertexAttributes::default()), - ) - }) - .collect::>(); + let field_attributes = get_field_attributes::( + VERTEX_ATTRIBUTE_NAME, + &ast.data, + ); let struct_name = &ast.ident; @@ -133,4 +112,4 @@ pub fn derive_as_vertex_buffer_descriptor(input: TokenStream) -> TokenStream { } } }) -} \ No newline at end of file +} diff --git a/crates/bevy_derive/src/attributes.rs b/crates/bevy_derive/src/attributes.rs new file mode 100644 index 0000000000..dabad20ae1 --- /dev/null +++ b/crates/bevy_derive/src/attributes.rs @@ -0,0 +1,50 @@ +use darling::FromMeta; +use syn::{Attribute, Data, DataStruct, Field, Fields}; + +pub fn get_field_attributes<'a, T, TArgs>( + attribute_name: &str, + data: &'a Data, +) -> Vec<(&'a Field, T)> +where + T: Default, + TArgs: FromMeta + Into + Default, +{ + let fields = match data { + Data::Struct(DataStruct { + fields: Fields::Named(fields), + .. + }) => &fields.named, + _ => panic!("expected a struct with named fields"), + }; + + fields + .iter() + .map(|f| { + ( + f, + f.attrs + .iter() + .find(|a| a.path.get_ident().as_ref().unwrap().to_string() == attribute_name) + .map(|a| { + TArgs::from_meta(&a.parse_meta().unwrap()) + .unwrap_or_else(|_err| TArgs::default()) + }) + .unwrap_or_else(|| TArgs::default()) + .into(), + ) + }) + .collect::>() +} + +pub fn get_attributes<'a, T, TArgs>(attribute_name: &str, attrs: &[Attribute]) -> T +where + T: Default, + TArgs: FromMeta + Into + Default, +{ + attrs + .iter() + .find(|a| a.path.get_ident().as_ref().unwrap().to_string() == attribute_name) + .map(|a| TArgs::from_meta(&a.parse_meta().unwrap()).unwrap_or_else(|_err| TArgs::default())) + .unwrap_or_else(|| TArgs::default()) + .into() +} diff --git a/crates/bevy_derive/src/entity_archetype.rs b/crates/bevy_derive/src/entity_archetype.rs index 90bfc88cfb..a114459fdb 100644 --- a/crates/bevy_derive/src/entity_archetype.rs +++ b/crates/bevy_derive/src/entity_archetype.rs @@ -1,15 +1,8 @@ use crate::modules::{get_modules, get_path}; -use darling::FromMeta; use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Fields, Ident}; -#[derive(FromMeta, Debug, Default)] -struct EntityArchetypeAttributeArgs { - #[darling(default)] - pub tag: Option, -} - pub fn derive_entity_archetype(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); let fields = match &ast.data { @@ -24,25 +17,8 @@ pub fn derive_entity_archetype(input: TokenStream) -> TokenStream { let bevy_app_path = get_path(&modules.bevy_app); let legion_path = get_path(&modules.legion); - let tag_fields = fields - .iter() - .filter(|f| { - f.attrs - .iter() - .find(|a| a.path.get_ident().as_ref().unwrap().to_string() == "tag") - .is_some() - }) - .map(|field| field.ident.as_ref().unwrap()) - .collect::>(); - let component_fields = fields .iter() - .filter(|f| { - f.attrs - .iter() - .find(|a| a.path.get_ident().as_ref().unwrap().to_string() == "tag") - .is_none() - }) .map(|field| field.ident.as_ref().unwrap()) .collect::>(); @@ -54,7 +30,7 @@ pub fn derive_entity_archetype(input: TokenStream) -> TokenStream { TokenStream::from(quote! { impl #impl_generics #bevy_app_path::EntityArchetype for #struct_name#ty_generics { fn insert(self, world: &mut #legion_path::prelude::World) -> #legion_path::prelude::Entity { - *world.insert((#(self.#tag_fields,)*), + *world.insert((), vec![( #(self.#component_fields,)* ) @@ -62,7 +38,7 @@ pub fn derive_entity_archetype(input: TokenStream) -> TokenStream { } fn insert_command_buffer(self, command_buffer: &mut #legion_path::prelude::CommandBuffer) -> #legion_path::prelude::Entity { - *command_buffer.insert((#(self.#tag_fields,)*), + *command_buffer.insert((), vec![( #(self.#component_fields,)* ) diff --git a/crates/bevy_derive/src/lib.rs b/crates/bevy_derive/src/lib.rs index 0885da75bc..bcff61c1d1 100644 --- a/crates/bevy_derive/src/lib.rs +++ b/crates/bevy_derive/src/lib.rs @@ -1,9 +1,12 @@ extern crate proc_macro; mod app_plugin; +mod attributes; mod bytes; mod entity_archetype; mod modules; +mod render_resources; +mod render_resource; mod resource; mod uniforms; mod as_vertex_buffer_descriptor; @@ -30,6 +33,16 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream { uniforms::derive_uniforms(input) } +#[proc_macro_derive(RenderResources, attributes(render_resources, module))] +pub fn derive_render_resources(input: TokenStream) -> TokenStream { + render_resources::derive_render_resources(input) +} + +#[proc_macro_derive(RenderResource, attributes(module))] +pub fn derive_render_resource(input: TokenStream) -> TokenStream { + render_resource::derive_render_resource(input) +} + #[proc_macro_derive(AsVertexBufferDescriptor, attributes(vertex, module))] pub fn derive_as_vertex_buffer_descriptor(input: TokenStream) -> TokenStream { as_vertex_buffer_descriptor::derive_as_vertex_buffer_descriptor(input) @@ -44,4 +57,4 @@ pub fn derive_entity_archetype(input: TokenStream) -> TokenStream { #[proc_macro_derive(DynamicAppPlugin)] pub fn derive_app_plugin(input: TokenStream) -> TokenStream { app_plugin::derive_dynamic_app_plugin(input) -} +} \ No newline at end of file diff --git a/crates/bevy_derive/src/render_resource.rs b/crates/bevy_derive/src/render_resource.rs new file mode 100644 index 0000000000..6a6a063df1 --- /dev/null +++ b/crates/bevy_derive/src/render_resource.rs @@ -0,0 +1,33 @@ +use crate::modules::{get_modules, get_path}; +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, DeriveInput, Path}; + +pub fn derive_render_resource(input: TokenStream) -> TokenStream { + let ast = parse_macro_input!(input as DeriveInput); + let modules = get_modules(&ast); + + let bevy_render_path: Path = get_path(&modules.bevy_render); + let bevy_asset_path: Path = get_path(&modules.bevy_asset); + let bevy_core_path: Path = get_path(&modules.bevy_core); + let struct_name = &ast.ident; + + TokenStream::from(quote! { + impl #bevy_render_path::render_resource::RenderResource for #struct_name { + fn resource_info(&self) -> Option<#bevy_render_path::render_resource::ResourceInfo> { + Some(#bevy_render_path::render_resource::ResourceInfo::Buffer(None)) + } + fn write_buffer_bytes(&self, buffer: &mut [u8]) { + use #bevy_core_path::bytes::Bytes; + self.write_bytes(buffer); + } + fn buffer_byte_len(&self) -> Option { + Some(self.byte_len()) + } + fn texture(&self) -> Option<#bevy_asset_path::Handle<#bevy_render_path::texture::Texture>> { + None + } + + } + }) +} diff --git a/crates/bevy_derive/src/render_resources.rs b/crates/bevy_derive/src/render_resources.rs new file mode 100644 index 0000000000..2d0c093155 --- /dev/null +++ b/crates/bevy_derive/src/render_resources.rs @@ -0,0 +1,148 @@ +use crate::{ + attributes::{get_attributes, get_field_attributes}, + modules::{get_modules, get_path}, +}; +use darling::FromMeta; +use proc_macro::TokenStream; +use quote::{format_ident, quote}; +use syn::{parse_macro_input, DeriveInput, Path}; + +#[derive(FromMeta, Debug, Default)] +struct RenderResourceAttributeArgs { + #[darling(default)] + pub ignore: Option, + #[darling(default)] + pub buffer: Option, + #[darling(default)] + pub from_self: Option, +} + +#[derive(Default)] +struct RenderResourceAttributes { + pub ignore: bool, + pub buffer: bool, + pub from_self: bool, +} + +impl From for RenderResourceAttributes { + fn from(args: RenderResourceAttributeArgs) -> Self { + Self { + ignore: args.ignore.unwrap_or(false), + buffer: args.buffer.unwrap_or(false), + from_self: args.from_self.unwrap_or(false), + } + } +} + +static RENDER_RESOURCE_ATTRIBUTE_NAME: &'static str = "render_resources"; + +pub fn derive_render_resources(input: TokenStream) -> TokenStream { + let ast = parse_macro_input!(input as DeriveInput); + let modules = get_modules(&ast); + + let bevy_render_path: Path = get_path(&modules.bevy_render); + let attributes = get_attributes::( + RENDER_RESOURCE_ATTRIBUTE_NAME, + &ast.attrs, + ); + let struct_name = &ast.ident; + let struct_name_string = struct_name.to_string(); + + if attributes.from_self { + TokenStream::from(quote! { + impl #bevy_render_path::render_resource::RenderResources for #struct_name { + fn render_resources_len(&self) -> usize { + 1 + } + + fn get_render_resource(&self, index: usize) -> Option<&dyn #bevy_render_path::render_resource::RenderResource> { + if index == 0 { + Some(self) + } else { + None + } + } + + fn get_render_resource_name(&self, index: usize) -> Option<&str> { + if index == 0 { + Some(#struct_name_string) + } else { + None + } + } + + fn iter_render_resources(&self) -> #bevy_render_path::render_resource::RenderResourceIterator { + #bevy_render_path::render_resource::RenderResourceIterator::new(self) + } + } + }) + } else { + let field_attributes = get_field_attributes::< + RenderResourceAttributes, + RenderResourceAttributeArgs, + >(RENDER_RESOURCE_ATTRIBUTE_NAME, &ast.data); + + let mut render_resource_names = Vec::new(); + let mut render_resource_fields = Vec::new(); + let mut render_resource_hints = Vec::new(); + for (field, attrs) in field_attributes.iter() { + if attrs.ignore { + continue; + } + + let field_ident = field.ident.as_ref().unwrap(); + let field_name = field_ident.to_string(); + render_resource_fields.push(field_ident); + render_resource_names.push(format!("{}_{}", struct_name, field_name)); + if attrs.buffer { + render_resource_hints.push(quote! {Some(#bevy_render_path::render_resource::RenderResourceHints::BUFFER)}) + } else { + render_resource_hints.push(quote! {None}) + } + } + + let render_resource_count = render_resource_names.len(); + let render_resource_indices = 0..render_resource_count; + + let struct_name_uppercase = struct_name_string.to_uppercase(); + let render_resource_names_ident = + format_ident!("{}_RENDER_RESOURCE_NAMES", struct_name_uppercase); + let render_resource_hints_ident = + format_ident!("{}_RENDER_RESOURCE_HINTS", struct_name_uppercase); + + TokenStream::from(quote! { + static #render_resource_names_ident: &[&str] = &[ + #(#render_resource_names,)* + ]; + + static #render_resource_hints_ident: &[Option<#bevy_render_path::render_resource::RenderResourceHints>] = &[ + #(#render_resource_hints,)* + ]; + + impl #bevy_render_path::render_resource::RenderResources for #struct_name { + fn render_resources_len(&self) -> usize { + #render_resource_count + } + + fn get_render_resource(&self, index: usize) -> Option<&dyn #bevy_render_path::render_resource::RenderResource> { + match index { + #(#render_resource_indices => Some(&self.#render_resource_fields),)* + _ => None, + } + } + + fn get_render_resource_name(&self, index: usize) -> Option<&str> { + Some(#render_resource_names_ident[index]) + } + + fn get_render_resource_hints(&self, index: usize) -> Option<#bevy_render_path::render_resource::RenderResourceHints> { + #render_resource_hints_ident[index].clone() + } + + fn iter_render_resources(&self) -> #bevy_render_path::render_resource::RenderResourceIterator { + #bevy_render_path::render_resource::RenderResourceIterator::new(self) + } + } + }) + } +} diff --git a/crates/bevy_derive/src/uniforms.rs b/crates/bevy_derive/src/uniforms.rs index 37ca65935c..d709486f4d 100644 --- a/crates/bevy_derive/src/uniforms.rs +++ b/crates/bevy_derive/src/uniforms.rs @@ -1,9 +1,12 @@ -use crate::modules::{get_modules, get_path}; +use crate::{ + attributes::get_field_attributes, + modules::{get_modules, get_path}, +}; 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, Path}; +use syn::{parse_macro_input, DeriveInput, Path}; #[derive(FromMeta, Debug, Default)] struct UniformAttributeArgs { @@ -42,34 +45,10 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream { let bevy_core_path: Path = get_path(&modules.bevy_core); let bevy_asset_path: Path = get_path(&modules.bevy_asset); - let fields = match &ast.data { - Data::Struct(DataStruct { - fields: Fields::Named(fields), - .. - }) => &fields.named, - _ => panic!("expected a struct with named fields"), - }; - - let field_attributes = fields - .iter() - .map(|f| { - ( - f, - f.attrs - .iter() - .find(|a| { - a.path.get_ident().as_ref().unwrap().to_string() == UNIFORM_ATTRIBUTE_NAME - }) - .map(|a| { - UniformAttributes::from( - UniformAttributeArgs::from_meta(&a.parse_meta().unwrap()) - .unwrap_or_else(|_err| UniformAttributeArgs::default()), - ) - }) - .unwrap_or_else(|| UniformAttributes::default()), - ) - }) - .collect::>(); + let field_attributes = get_field_attributes::( + UNIFORM_ATTRIBUTE_NAME, + &ast.data, + ); let struct_name = &ast.ident; @@ -141,34 +120,18 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream { } fn get_field_bind_type(&self, name: &str) -> Option<#bevy_render_path::shader::FieldBindType> { - use #bevy_render_path::shader::GetFieldBindType; - match name { - #(#active_uniform_field_name_strings => #get_field_bind_types,)* - _ => None, - } + None } fn get_uniform_texture(&self, name: &str) -> Option<#bevy_asset_path::Handle<#bevy_render_path::texture::Texture>> { - use #bevy_render_path::shader::GetTexture; - match name { - #(#texture_and_sampler_name_strings => self.#texture_and_sampler_name_idents.get_texture(),)* - _ => None, - } + None } fn write_uniform_bytes(&self, name: &str, buffer: &mut [u8]) { use #bevy_core_path::bytes::Bytes; - match name { - #(#uniform_name_strings => self.#active_uniform_field_names.write_bytes(buffer),)* - _ => {}, - } } fn uniform_byte_len(&self, name: &str) -> usize { - use #bevy_core_path::bytes::Bytes; - match name { - #(#uniform_name_strings => self.#active_uniform_field_names.byte_len(),)* - _ => 0, - } + 0 } // TODO: move this to field_info and add has_shader_def(&self, &str) -> bool @@ -194,7 +157,6 @@ pub fn derive_uniform(input: TokenStream) -> TokenStream { let modules = get_modules(&ast); let bevy_asset_path = get_path(&modules.bevy_asset); - let bevy_core_path = get_path(&modules.bevy_core); let bevy_render_path = get_path(&modules.bevy_render); let generics = ast.generics; @@ -218,26 +180,13 @@ pub fn derive_uniform(input: TokenStream) -> TokenStream { } fn get_field_bind_type(&self, name: &str) -> Option<#bevy_render_path::shader::FieldBindType> { - use #bevy_render_path::shader::GetFieldBindType; - match name { - #struct_name_string => self.get_bind_type(), - _ => None, - } + None } fn write_uniform_bytes(&self, name: &str, buffer: &mut [u8]) { - use #bevy_core_path::bytes::Bytes; - match name { - #struct_name_string => self.write_bytes(buffer), - _ => {}, - } } fn uniform_byte_len(&self, name: &str) -> usize { - use #bevy_core_path::bytes::Bytes; - match name { - #struct_name_string => self.byte_len(), - _ => 0, - } + 0 } fn get_uniform_texture(&self, name: &str) -> Option<#bevy_asset_path::Handle<#bevy_render_path::texture::Texture>> { diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index 4947907c86..5cf832d602 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -1,8 +1,7 @@ use bevy_asset::{self, Handle}; -use bevy_derive::Uniforms; -use bevy_render::{texture::Texture, Color}; +use bevy_render::{render_resource::RenderResources, shader::Uniforms, texture::Texture, Color}; -#[derive(Uniforms)] +#[derive(Uniforms, RenderResources)] pub struct StandardMaterial { pub albedo: Color, #[uniform(shader_def)] diff --git a/crates/bevy_render/src/color.rs b/crates/bevy_render/src/color.rs index 453e3f234e..0b490aed44 100644 --- a/crates/bevy_render/src/color.rs +++ b/crates/bevy_render/src/color.rs @@ -1,5 +1,5 @@ use super::texture::Texture; -use crate::shader::ShaderDefSuffixProvider; +use crate::{render_resource::{ResourceInfo, RenderResource}, shader::ShaderDefSuffixProvider, impl_render_resource_bytes}; use bevy_asset::Handle; use bevy_core::bytes::{Byteable, Bytes}; use bevy_property::Property; @@ -138,3 +138,5 @@ impl ShaderDefSuffixProvider for ColorSource { } } } + +impl_render_resource_bytes!(Color); \ No newline at end of file diff --git a/crates/bevy_render/src/draw_target/draw_targets/meshes_draw_target.rs b/crates/bevy_render/src/draw_target/draw_targets/meshes_draw_target.rs index 3add484f7b..f05f70d119 100644 --- a/crates/bevy_render/src/draw_target/draw_targets/meshes_draw_target.rs +++ b/crates/bevy_render/src/draw_target/draw_targets/meshes_draw_target.rs @@ -45,7 +45,7 @@ impl DrawTarget for MeshesDrawTarget { render_resources.get_resource_info( index_buffer_resource, &mut |resource_info| match resource_info { - Some(ResourceInfo::Buffer(buffer_info)) => { + Some(ResourceInfo::Buffer(Some(buffer_info))) => { current_mesh_index_len = (buffer_info.size / 2) as u32 } _ => panic!("expected a buffer type"), diff --git a/crates/bevy_render/src/render_graph/nodes/uniform_node.rs b/crates/bevy_render/src/render_graph/nodes/uniform_node.rs index cec2083bb0..cb4ab623e9 100644 --- a/crates/bevy_render/src/render_graph/nodes/uniform_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/uniform_node.rs @@ -1,16 +1,16 @@ use crate::{ render_graph::{CommandQueue, Node, ResourceSlots, SystemNode}, render_resource::{ - BufferInfo, BufferUsage, EntitiesWaitingForAssets, RenderResourceId, - RenderResourceAssignment, RenderResourceAssignments, RenderResourceAssignmentsId, + self, BufferInfo, BufferUsage, EntitiesWaitingForAssets, RenderResourceAssignment, + RenderResourceAssignments, RenderResourceAssignmentsId, RenderResourceId, RenderResourceHints, }, renderer::{RenderContext, RenderResourceContext, RenderResources}, - shader::{Uniforms, FieldBindType}, texture, Renderable, }; use bevy_asset::{Assets, Handle}; use legion::prelude::*; +use render_resource::ResourceInfo; use std::{collections::HashMap, marker::PhantomData}; pub const BIND_BUFFER_ALIGNMENT: usize = 256; @@ -53,25 +53,28 @@ impl BufferArrayStatus { struct UniformBufferArrays where - T: Uniforms, + T: render_resource::RenderResources, { uniform_arrays: Vec>, _marker: PhantomData, } -impl UniformBufferArrays +impl Default for UniformBufferArrays where - T: Uniforms, + T: render_resource::RenderResources, { - fn new() -> Self { - let mut uniform_arrays = Vec::new(); - let field_infos = T::get_field_infos(); - uniform_arrays.resize_with(field_infos.len(), || None); - UniformBufferArrays { - uniform_arrays, - _marker: PhantomData::default(), + fn default() -> Self { + Self { + uniform_arrays: Default::default(), + _marker: Default::default(), } } +} + +impl UniformBufferArrays +where + T: render_resource::RenderResources, +{ fn reset_new_item_counts(&mut self) { for buffer_status in self.uniform_arrays.iter_mut() { if let Some((_name, buffer_status)) = buffer_status { @@ -81,15 +84,19 @@ where } fn increment_uniform_counts(&mut self, uniforms: &T) { - for (i, field_info) in T::get_field_infos().iter().enumerate() { - if let Some(FieldBindType::Uniform { size }) | Some(FieldBindType::Buffer { size }) = - uniforms.get_field_bind_type(&field_info.name) - { + if self.uniform_arrays.len() != uniforms.render_resources_len() { + self.uniform_arrays + .resize_with(uniforms.render_resources_len(), || None); + } + for (i, render_resource) in uniforms.iter_render_resources().enumerate() { + if let Some(ResourceInfo::Buffer(_)) = render_resource.resource_info() { + let render_resource_name = uniforms.get_render_resource_name(i).unwrap(); + let size = render_resource.buffer_byte_len().unwrap(); if let Some((ref _name, ref mut buffer_array_status)) = self.uniform_arrays[i] { buffer_array_status.new_item_count += 1; } else { self.uniform_arrays[i] = Some(( - field_info.uniform_name.to_string(), + render_resource_name.to_string(), BufferArrayStatus { new_item_count: 1, queued_buffer_writes: Vec::new(), @@ -182,10 +189,11 @@ where render_resource_assignments: &mut RenderResourceAssignments, staging_buffer: &mut [u8], ) { - for (i, field_info) in T::get_field_infos().iter().enumerate() { - let bind_type = uniforms.get_field_bind_type(&field_info.name); - match bind_type { - Some(FieldBindType::Uniform { size }) | Some(FieldBindType::Buffer { size }) => { + for (i, render_resource) in uniforms.iter_render_resources().enumerate() { + match render_resource.resource_info() { + Some(ResourceInfo::Buffer(_)) => { + let size = render_resource.buffer_byte_len().unwrap(); + let render_resource_name = uniforms.get_render_resource_name(i).unwrap(); let (_name, uniform_buffer_status) = self.uniform_arrays[i].as_mut().unwrap(); let range = 0..size as u64; let (target_buffer, target_offset) = if dynamic_uniforms { @@ -193,7 +201,7 @@ where let index = uniform_buffer_status .get_or_assign_index(render_resource_assignments.id); render_resource_assignments.set( - &field_info.uniform_name, + render_resource_name, RenderResourceAssignment::Buffer { resource: buffer, dynamic_index: Some( @@ -204,16 +212,18 @@ where ); (buffer, index * uniform_buffer_status.aligned_size) } else { - let resource = match render_resource_assignments - .get(field_info.uniform_name) - { + let resource = match render_resource_assignments.get(render_resource_name) { Some(assignment) => assignment.get_resource(), None => { - let usage = if let Some(FieldBindType::Buffer { .. }) = bind_type { - BufferUsage::STORAGE - } else { - BufferUsage::UNIFORM - }; + // TODO: RE-ADD support for BufferUsage::STORAGE type + let mut usage = BufferUsage::UNIFORM; + + if let Some(render_resource_hints) = uniforms.get_render_resource_hints(i) { + if render_resource_hints.contains(RenderResourceHints::BUFFER) { + usage = BufferUsage::STORAGE + } + } + let resource = render_resources.create_buffer(BufferInfo { size, buffer_usage: BufferUsage::COPY_DST | usage, @@ -221,7 +231,7 @@ where }); render_resource_assignments.set( - &field_info.uniform_name, + render_resource_name, RenderResourceAssignment::Buffer { resource, range, @@ -238,23 +248,9 @@ where let staging_buffer_start = uniform_buffer_status.staging_buffer_offset + (uniform_buffer_status.queued_buffer_writes.len() * uniform_buffer_status.item_size); - let uniform_byte_len = uniforms.uniform_byte_len(&field_info.uniform_name); - if uniform_byte_len > 0 { - if size != uniform_byte_len { - panic!("The number of bytes produced for {} do not match the expected count. Actual: {}. Expected: {}.", field_info.uniform_name, uniform_byte_len, size); - } - - uniforms.write_uniform_bytes( - &field_info.uniform_name, - &mut staging_buffer - [staging_buffer_start..(staging_buffer_start + uniform_byte_len)], - ); - } else { - panic!( - "failed to get data from uniform: {}", - field_info.uniform_name - ); - }; + render_resource.write_buffer_bytes( + &mut staging_buffer[staging_buffer_start..(staging_buffer_start + size)], + ); uniform_buffer_status .queued_buffer_writes @@ -263,7 +259,8 @@ where offset: target_offset, }); } - Some(FieldBindType::Texture) => { /* ignore textures */ } + Some(ResourceInfo::Texture(_)) => { /* ignore textures */ } + Some(ResourceInfo::Sampler) => { /* ignore samplers */ } None => { /* ignore None */ } } } @@ -347,7 +344,7 @@ where #[derive(Default)] pub struct UniformNode where - T: Uniforms, + T: render_resource::RenderResources, { command_queue: CommandQueue, dynamic_uniforms: bool, @@ -356,7 +353,7 @@ where impl UniformNode where - T: Uniforms, + T: render_resource::RenderResources, { pub fn new(dynamic_uniforms: bool) -> Self { UniformNode { @@ -369,7 +366,7 @@ where impl Node for UniformNode where - T: Uniforms, + T: render_resource::RenderResources, { fn update( &mut self, @@ -385,11 +382,11 @@ where impl SystemNode for UniformNode where - T: Uniforms, + T: render_resource::RenderResources, { fn get_system(&self) -> Box { let mut command_queue = self.command_queue.clone(); - let mut uniform_buffer_arrays = UniformBufferArrays::::new(); + let mut uniform_buffer_arrays = UniformBufferArrays::::default(); let dynamic_uniforms = self.dynamic_uniforms; // TODO: maybe run "update" here SystemBuilder::new(format!( @@ -505,7 +502,7 @@ where #[derive(Default)] pub struct AssetUniformNode where - T: Uniforms, + T: render_resource::RenderResources, { command_queue: CommandQueue, dynamic_uniforms: bool, @@ -514,7 +511,7 @@ where impl AssetUniformNode where - T: Uniforms, + T: render_resource::RenderResources, { pub fn new(dynamic_uniforms: bool) -> Self { AssetUniformNode { @@ -527,7 +524,7 @@ where impl Node for AssetUniformNode where - T: Uniforms, + T: render_resource::RenderResources, { fn update( &mut self, @@ -543,11 +540,11 @@ where impl SystemNode for AssetUniformNode where - T: Uniforms, + T: render_resource::RenderResources, { fn get_system(&self) -> Box { let mut command_queue = self.command_queue.clone(); - let mut uniform_buffer_arrays = UniformBufferArrays::::new(); + let mut uniform_buffer_arrays = UniformBufferArrays::::default(); let dynamic_uniforms = self.dynamic_uniforms; // TODO: maybe run "update" here SystemBuilder::new("uniform_resource_provider") @@ -677,12 +674,13 @@ fn setup_uniform_texture_resources( entities_waiting_for_assets: &EntitiesWaitingForAssets, render_resource_assignments: &mut RenderResourceAssignments, ) where - T: Uniforms, + T: render_resource::RenderResources, { - for field_info in T::get_field_infos().iter() { - let bind_type = uniforms.get_field_bind_type(&field_info.name); - if let Some(FieldBindType::Texture) = bind_type { - if let Some(texture_handle) = uniforms.get_uniform_texture(&field_info.texture_name) { + for (i, render_resource) in uniforms.iter_render_resources().enumerate() { + if let Some(ResourceInfo::Texture(_)) = render_resource.resource_info() { + let render_resource_name = uniforms.get_render_resource_name(i).unwrap(); + let sampler_name = format!("{}_sampler", render_resource_name); + if let Some(texture_handle) = render_resource.texture() { if let Some(texture_resource) = render_resource_context .get_asset_resource(texture_handle, texture::TEXTURE_ASSET_INDEX) { @@ -690,11 +688,11 @@ fn setup_uniform_texture_resources( .get_asset_resource(texture_handle, texture::SAMPLER_ASSET_INDEX) .unwrap(); render_resource_assignments.set( - field_info.texture_name, + render_resource_name, RenderResourceAssignment::Texture(texture_resource), ); render_resource_assignments.set( - field_info.sampler_name, + &sampler_name, RenderResourceAssignment::Sampler(sampler_resource), ); continue; diff --git a/crates/bevy_render/src/render_resource/render_resource.rs b/crates/bevy_render/src/render_resource/render_resource.rs index 567e204b73..e22a3c6c77 100644 --- a/crates/bevy_render/src/render_resource/render_resource.rs +++ b/crates/bevy_render/src/render_resource/render_resource.rs @@ -1,6 +1,12 @@ +use super::ResourceInfo; +use crate::texture::Texture; +use bevy_asset::Handle; use uuid::Uuid; -// TODO: Rename to RenderResourceId +use bevy_core::bytes::{Byteable, Bytes}; +pub use bevy_derive::{RenderResource, RenderResources}; +use glam::{Mat4, Vec2, Vec3, Vec4}; + #[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)] pub struct RenderResourceId(Uuid); @@ -9,3 +15,101 @@ impl RenderResourceId { RenderResourceId(Uuid::new_v4()) } } + +bitflags::bitflags! { + #[repr(transparent)] + pub struct RenderResourceHints: u32 { + const BUFFER = 1; + } +} + +pub trait RenderResource { + fn resource_info(&self) -> Option; + fn write_buffer_bytes(&self, buffer: &mut [u8]); + fn buffer_byte_len(&self) -> Option; + // TODO: consider making these panic by default, but return non-options + fn texture(&self) -> Option>; +} + +pub trait RenderResources: Send + Sync + 'static { + fn render_resources_len(&self) -> usize; + fn get_render_resource(&self, index: usize) -> Option<&dyn RenderResource>; + fn get_render_resource_name(&self, index: usize) -> Option<&str>; + fn get_render_resource_hints(&self, _index: usize) -> Option { + None + } + fn iter_render_resources(&self) -> RenderResourceIterator; +} + +pub struct RenderResourceIterator<'a> { + render_resources: &'a dyn RenderResources, + index: usize, +} + +impl<'a> RenderResourceIterator<'a> { + pub fn new(render_resources: &'a dyn RenderResources) -> Self { + Self { + render_resources, + index: 0, + } + } +} +impl<'a> Iterator for RenderResourceIterator<'a> { + type Item = &'a dyn RenderResource; + fn next(&mut self) -> Option { + if self.index == self.render_resources.render_resources_len() { + None + } else { + let render_resource = self + .render_resources + .get_render_resource(self.index) + .unwrap(); + self.index += 1; + Some(render_resource) + } + } +} + +#[macro_export] +macro_rules! impl_render_resource_bytes { + ($ty:ident) => { + impl RenderResource for $ty { + fn resource_info(&self) -> Option { + Some(ResourceInfo::Buffer(None)) + } + fn write_buffer_bytes(&self, buffer: &mut [u8]) { + self.write_bytes(buffer); + } + fn buffer_byte_len(&self) -> Option { + Some(self.byte_len()) + } + fn texture(&self) -> Option> { + None + } + } + }; +} + +// TODO: when specialization lands, replace these with impl RenderResource for T where T: Bytes +impl_render_resource_bytes!(Vec2); +impl_render_resource_bytes!(Vec3); +impl_render_resource_bytes!(Vec4); +impl_render_resource_bytes!(Mat4); + +impl RenderResource for Vec +where + T: Sized + Byteable, +{ + fn resource_info(&self) -> Option { + Some(ResourceInfo::Buffer(None)) + } + fn write_buffer_bytes(&self, buffer: &mut [u8]) { + self.write_bytes(buffer); + } + fn buffer_byte_len(&self) -> Option { + Some(self.byte_len()) + } + fn texture(&self) -> Option> { + None + } +} diff --git a/crates/bevy_render/src/render_resource/resource_info.rs b/crates/bevy_render/src/render_resource/resource_info.rs index 369b6b1480..d6214147f1 100644 --- a/crates/bevy_render/src/render_resource/resource_info.rs +++ b/crates/bevy_render/src/render_resource/resource_info.rs @@ -17,7 +17,7 @@ impl Default for BufferInfo { #[derive(Debug, Clone, Eq, PartialEq)] pub enum ResourceInfo { - Buffer(BufferInfo), - Texture(TextureDescriptor), + Buffer(Option), + Texture(Option), Sampler, -} +} \ No newline at end of file diff --git a/crates/bevy_render/src/renderer/headless_render_resource_context.rs b/crates/bevy_render/src/renderer/headless_render_resource_context.rs index 76925b1664..f84cb4c6d6 100644 --- a/crates/bevy_render/src/renderer/headless_render_resource_context.rs +++ b/crates/bevy_render/src/renderer/headless_render_resource_context.rs @@ -43,12 +43,12 @@ impl RenderResourceContext for HeadlessRenderResourceContext { } fn create_texture(&self, texture_descriptor: TextureDescriptor) -> RenderResourceId { let resource = RenderResourceId::new(); - self.add_resource_info(resource, ResourceInfo::Texture(texture_descriptor)); + self.add_resource_info(resource, ResourceInfo::Texture(Some(texture_descriptor))); resource } fn create_buffer(&self, buffer_info: BufferInfo) -> RenderResourceId { let resource = RenderResourceId::new(); - self.add_resource_info(resource, ResourceInfo::Buffer(buffer_info)); + self.add_resource_info(resource, ResourceInfo::Buffer(Some(buffer_info))); resource } fn create_buffer_mapped( @@ -62,7 +62,7 @@ impl RenderResourceContext for HeadlessRenderResourceContext { } fn create_buffer_with_data(&self, buffer_info: BufferInfo, _data: &[u8]) -> RenderResourceId { let resource = RenderResourceId::new(); - self.add_resource_info(resource, ResourceInfo::Buffer(buffer_info)); + self.add_resource_info(resource, ResourceInfo::Buffer(Some(buffer_info))); resource } fn create_shader_module(&self, _shader_handle: Handle, _shaders: &Assets) {} diff --git a/crates/bevy_render/src/shader/uniform.rs b/crates/bevy_render/src/shader/uniform.rs index 53e74e1637..be231b5ab4 100644 --- a/crates/bevy_render/src/shader/uniform.rs +++ b/crates/bevy_render/src/shader/uniform.rs @@ -1,7 +1,5 @@ -use crate::{color::ColorSource, pipeline::BindType, texture::Texture, Renderable}; - +use crate::{pipeline::BindType, texture::Texture, Renderable}; use bevy_asset::{Assets, Handle}; -use bevy_core::bytes::Bytes; use legion::prelude::*; pub use bevy_derive::{Uniform, Uniforms}; @@ -78,82 +76,6 @@ pub struct FieldInfo { pub sampler_name: &'static str, } -pub trait GetFieldBindType { - fn get_bind_type(&self) -> Option; -} - -impl GetFieldBindType for ColorSource { - fn get_bind_type(&self) -> Option { - match *self { - ColorSource::Texture(_) => Some(FieldBindType::Texture), - ColorSource::Color(color) => color.get_bind_type(), - } - } -} - -impl GetFieldBindType for Option> { - fn get_bind_type(&self) -> Option { - match *self { - Some(_) => Some(FieldBindType::Texture), - None => None, - } - } -} - -impl GetFieldBindType for Handle { - fn get_bind_type(&self) -> Option { - Some(FieldBindType::Texture) - } -} - -impl GetFieldBindType for T -where - T: Bytes, -{ - // TODO: this breaks if get_bytes_ref() isn't supported for a datatype - default fn get_bind_type(&self) -> Option { - Some(FieldBindType::Uniform { - size: self.byte_len(), - }) - } -} - -pub trait GetTexture { - fn get_texture(&self) -> Option> { - None - } -} - -impl GetTexture for T -where - T: Bytes, -{ - default fn get_texture(&self) -> Option> { - None - } -} - -impl GetTexture for Handle { - fn get_texture(&self) -> Option> { - Some(self.clone()) - } -} - -impl GetTexture for Option> { - fn get_texture(&self) -> Option> { - *self - } -} - -impl GetTexture for ColorSource { - fn get_texture(&self) -> Option> { - match self { - ColorSource::Color(_) => None, - ColorSource::Texture(texture) => Some(texture.clone()), - } - } -} - pub struct UniformInfo<'a> { pub name: &'a str, pub bind_type: BindType, diff --git a/crates/bevy_render/src/shader/uniforms.rs b/crates/bevy_render/src/shader/uniforms.rs index 9283898bce..ba9a9578c4 100644 --- a/crates/bevy_render/src/shader/uniforms.rs +++ b/crates/bevy_render/src/shader/uniforms.rs @@ -1,45 +1,27 @@ -use crate::{ - shader::{FieldBindType, FieldInfo, GetFieldBindType, Uniforms}, - texture::Texture, -}; -use bevy_asset::Handle; -use bevy_core::bytes::Bytes; +use crate::render_resource::{RenderResource, RenderResourceIterator, RenderResources}; -static TRANSFORM_FIELD_INFOS: &[FieldInfo] = &[FieldInfo { - name: "transform", - uniform_name: "Transform", - texture_name: "", - sampler_name: "", -}]; - -impl Uniforms for bevy_transform::prelude::Transform { - fn get_field_infos() -> &'static [FieldInfo] { - TRANSFORM_FIELD_INFOS +impl RenderResources for bevy_transform::prelude::Transform { + fn render_resources_len(&self) -> usize { + 1 } - fn get_shader_defs(&self) -> Option> { - None - } - fn get_field_bind_type(&self, name: &str) -> Option { - match name { - "transform" => self.value.get_bind_type(), - _ => None, + fn get_render_resource(&self, index: usize) -> Option<&dyn RenderResource> { + if index == 0 { + Some(&self.value) + } else { + None } } - fn get_uniform_texture(&self, _name: &str) -> Option> { - None + + fn get_render_resource_name(&self, index: usize) -> Option<&str> { + if index == 0 { + Some("Transform") + } else { + None + } } - fn write_uniform_bytes(&self, name: &str, buffer: &mut [u8]) { - match name { - "Transform" => self.value.write_bytes(buffer), - _ => {} - } - } - fn uniform_byte_len(&self, name: &str) -> usize { - match name { - "Transform" => self.value.byte_len(), - _ => 0, - } + fn iter_render_resources(&self) -> RenderResourceIterator { + RenderResourceIterator::new(self) } } diff --git a/crates/bevy_render/src/texture/texture.rs b/crates/bevy_render/src/texture/texture.rs index 7a71293e64..6eabc3df86 100644 --- a/crates/bevy_render/src/texture/texture.rs +++ b/crates/bevy_render/src/texture/texture.rs @@ -1,7 +1,7 @@ use super::{SamplerDescriptor, TextureDescriptor}; use crate::{ renderer::{RenderResourceContext, RenderResources}, - shader::ShaderDefSuffixProvider, + shader::ShaderDefSuffixProvider, render_resource::{ResourceInfo, RenderResource}, }; use bevy_app::{EventReader, Events}; use bevy_asset::{AssetEvent, Assets, Handle}; @@ -121,3 +121,31 @@ impl ShaderDefSuffixProvider for Option> { } } } + +impl RenderResource for Option> { + fn resource_info(&self) -> Option { + self.map(|_texture| ResourceInfo::Texture(None)) + } + fn write_buffer_bytes(&self, _buffer: &mut [u8]) { + } + fn buffer_byte_len(&self) -> Option { + None + } + fn texture(&self) -> Option> { + self.clone() + } +} + +impl RenderResource for Handle { + fn resource_info(&self) -> Option { + Some(ResourceInfo::Texture(None)) + } + fn write_buffer_bytes(&self, _buffer: &mut [u8]) { + } + fn buffer_byte_len(&self) -> Option { + None + } + fn texture(&self) -> Option> { + Some(self.clone()) + } +} \ No newline at end of file diff --git a/crates/bevy_sprite/Cargo.toml b/crates/bevy_sprite/Cargo.toml index 0e9a48d75d..f876e3798c 100644 --- a/crates/bevy_sprite/Cargo.toml +++ b/crates/bevy_sprite/Cargo.toml @@ -11,7 +11,6 @@ bevy_app = { path = "../bevy_app" } bevy_core = { path = "../bevy_core" } bevy_asset = { path = "../bevy_asset" } bevy_type_registry = { path = "../bevy_type_registry" } -bevy_derive = { path = "../bevy_derive" } bevy_render = { path = "../bevy_render" } bevy_transform = { path = "../bevy_transform" } diff --git a/crates/bevy_sprite/src/color_material.rs b/crates/bevy_sprite/src/color_material.rs index d5157e3e09..b3652eea1a 100644 --- a/crates/bevy_sprite/src/color_material.rs +++ b/crates/bevy_sprite/src/color_material.rs @@ -1,8 +1,7 @@ use bevy_asset::{self, Handle}; -use bevy_derive::Uniforms; -use bevy_render::{texture::Texture, Color}; +use bevy_render::{texture::Texture, Color, render_resource::RenderResources, shader::Uniforms}; -#[derive(Uniforms)] +#[derive(Uniforms, RenderResources)] pub struct ColorMaterial { pub color: Color, #[uniform(shader_def)] diff --git a/crates/bevy_sprite/src/entity.rs b/crates/bevy_sprite/src/entity.rs index 717c87c262..f4cbec75ed 100644 --- a/crates/bevy_sprite/src/entity.rs +++ b/crates/bevy_sprite/src/entity.rs @@ -3,7 +3,7 @@ use crate::{ TextureAtlasSprite, QUAD_HANDLE, SPRITE_SHEET_PIPELINE_HANDLE, }; use bevy_asset::Handle; -use bevy_derive::EntityArchetype; +use bevy_app::EntityArchetype; use bevy_render::{mesh::Mesh, Renderable}; #[derive(EntityArchetype)] diff --git a/crates/bevy_sprite/src/quad.rs b/crates/bevy_sprite/src/quad.rs index 98a872fd63..183aa8eb63 100644 --- a/crates/bevy_sprite/src/quad.rs +++ b/crates/bevy_sprite/src/quad.rs @@ -1,7 +1,9 @@ -use bevy_derive::{Bytes, Uniform}; use glam::Vec2; +use bevy_render::{shader::Uniform, render_resource::{RenderResources, RenderResource}}; +use bevy_core::bytes::Bytes; #[repr(C)] -#[derive(Default, Clone, Copy, Debug, Uniform, Bytes)] +#[derive(Default, Clone, Copy, Debug, Uniform, RenderResources, RenderResource, Bytes)] +#[render_resources(from_self)] pub struct Quad { pub position: Vec2, pub size: Vec2, diff --git a/crates/bevy_sprite/src/texture_atlas.rs b/crates/bevy_sprite/src/texture_atlas.rs index 5a31aa7aba..18f0475ef8 100644 --- a/crates/bevy_sprite/src/texture_atlas.rs +++ b/crates/bevy_sprite/src/texture_atlas.rs @@ -1,24 +1,27 @@ use crate::Rect; use bevy_asset::Handle; -use bevy_derive::{Bytes, Uniform, Uniforms}; -use bevy_render::texture::Texture; +use bevy_render::{texture::Texture, render_resource::{RenderResources, RenderResource}, shader::{Uniforms, Uniform}}; +use bevy_core::bytes::Bytes; use glam::{Vec2, Vec3}; use std::collections::HashMap; -#[derive(Uniforms)] +#[derive(Uniforms, RenderResources)] pub struct TextureAtlas { pub texture: Handle, // TODO: add support to Uniforms derive to write dimensions and sprites to the same buffer pub dimensions: Vec2, #[uniform(buffer)] + #[render_resources(buffer)] pub textures: Vec, #[uniform(ignore)] + #[render_resources(ignore)] pub texture_handles: Option, usize>>, } // NOTE: cannot do `unsafe impl Byteable` here because Vec3 takes up the space of a Vec4. If/when glam changes this we can swap out // Bytes for Byteable as a micro-optimization. https://github.com/bitshifter/glam-rs/issues/36 -#[derive(Uniform, Bytes, Default)] +#[derive(Uniform, Bytes, RenderResources, RenderResource, Default)] +#[render_resources(from_self)] pub struct TextureAtlasSprite { pub position: Vec3, pub scale: f32, diff --git a/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs b/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs index ccbf7e20d5..5c48cceee3 100644 --- a/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs +++ b/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs @@ -152,7 +152,7 @@ impl RenderResourceContext for WgpuRenderResourceContext { let texture_view = texture.create_default_view(); let resource = RenderResourceId::new(); - resource_info.insert(resource, ResourceInfo::Texture(texture_descriptor)); + resource_info.insert(resource, ResourceInfo::Texture(Some(texture_descriptor))); texture_views.insert(resource, texture_view); textures.insert(resource, texture); resource @@ -171,7 +171,7 @@ impl RenderResourceContext for WgpuRenderResourceContext { }); let resource = RenderResourceId::new(); - resource_info.insert(resource, ResourceInfo::Buffer(buffer_info)); + resource_info.insert(resource, ResourceInfo::Buffer(Some(buffer_info))); buffers.insert(resource, buffer); resource } @@ -202,7 +202,7 @@ impl RenderResourceContext for WgpuRenderResourceContext { let resource = RenderResourceId::new(); let mut resource_info = self.resources.resource_info.write().unwrap(); let mut buffers = self.resources.buffers.write().unwrap(); - resource_info.insert(resource, ResourceInfo::Buffer(buffer_info)); + resource_info.insert(resource, ResourceInfo::Buffer(Some(buffer_info))); buffers.insert(resource, buffer); resource } @@ -218,7 +218,7 @@ impl RenderResourceContext for WgpuRenderResourceContext { .create_buffer_with_data(data, buffer_info.buffer_usage.wgpu_into()); let resource = RenderResourceId::new(); - resource_info.insert(resource, ResourceInfo::Buffer(buffer_info)); + resource_info.insert(resource, ResourceInfo::Buffer(Some(buffer_info))); buffers.insert(resource, buffer); resource } diff --git a/crates/bevy_wgpu/src/wgpu_render_pass.rs b/crates/bevy_wgpu/src/wgpu_render_pass.rs index 1849e957fa..6a005fd07c 100644 --- a/crates/bevy_wgpu/src/wgpu_render_pass.rs +++ b/crates/bevy_wgpu/src/wgpu_render_pass.rs @@ -83,7 +83,7 @@ impl<'a> RenderPass for WgpuRenderPass<'a> { self.render_context.resources().get_resource_info( index_buffer, &mut |resource_info| match resource_info { - Some(ResourceInfo::Buffer(buffer_info)) => { + Some(ResourceInfo::Buffer(Some(buffer_info))) => { indices = Some(0..(buffer_info.size / 2) as u32) } _ => panic!("expected a buffer type"), diff --git a/examples/shader/shader_custom_material.rs b/examples/shader/shader_custom_material.rs index 77dc25378d..66a0d1a461 100644 --- a/examples/shader/shader_custom_material.rs +++ b/examples/shader/shader_custom_material.rs @@ -8,7 +8,7 @@ fn main() { .run(); } -#[derive(Uniforms, Default)] +#[derive(Uniforms, RenderResources, Default)] struct MyMaterial { pub color: Color, } diff --git a/examples/shader/shader_defs.rs b/examples/shader/shader_defs.rs index f8c38f6268..feca9eab60 100644 --- a/examples/shader/shader_defs.rs +++ b/examples/shader/shader_defs.rs @@ -12,10 +12,11 @@ fn main() { .run(); } -#[derive(Uniforms, Default)] +#[derive(Uniforms, RenderResources, Default)] struct MyMaterial { pub color: Color, #[uniform(ignore, shader_def)] + #[render_resources(ignore)] pub always_red: bool, } diff --git a/src/prelude.rs b/src/prelude.rs index 997ed2edda..8b22b57cf8 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -26,6 +26,7 @@ pub use crate::{ RenderGraph, }, shader::{Shader, ShaderDefSuffixProvider, ShaderStage, ShaderStages, Uniforms}, + render_resource::RenderResources, texture::Texture, Camera, Color, ColorSource, OrthographicProjection, PerspectiveProjection, Renderable, },