remove old uniform system

This commit is contained in:
Carter Anderson 2020-06-07 22:32:55 -07:00
parent 62c434274f
commit be23f119d5
17 changed files with 54 additions and 336 deletions

View File

@ -9,7 +9,6 @@ mod render_resources;
mod render_resource;
mod resource;
mod shader_defs;
mod uniforms;
mod as_vertex_buffer_descriptor;
use proc_macro::TokenStream;
@ -24,16 +23,6 @@ pub fn derive_bytes(input: TokenStream) -> TokenStream {
bytes::derive_bytes(input)
}
#[proc_macro_derive(Uniform, attributes(uniform, module))]
pub fn derive_uniform(input: TokenStream) -> TokenStream {
uniforms::derive_uniform(input)
}
#[proc_macro_derive(Uniforms, attributes(uniform, module))]
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)

View File

@ -1,196 +0,0 @@
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, DeriveInput, Path};
#[derive(FromMeta, Debug, Default)]
struct UniformAttributeArgs {
#[darling(default)]
pub ignore: Option<bool>,
#[darling(default)]
pub shader_def: Option<bool>,
#[darling(default)]
pub buffer: Option<bool>,
}
#[derive(Default)]
struct UniformAttributes {
pub ignore: bool,
pub shader_def: bool,
pub buffer: bool,
}
impl From<UniformAttributeArgs> for UniformAttributes {
fn from(args: UniformAttributeArgs) -> Self {
UniformAttributes {
ignore: args.ignore.unwrap_or(false),
shader_def: args.shader_def.unwrap_or(false),
buffer: args.buffer.unwrap_or(false),
}
}
}
static UNIFORM_ATTRIBUTE_NAME: &'static str = "uniform";
pub fn derive_uniforms(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_core_path: Path = get_path(&modules.bevy_core);
let bevy_asset_path: Path = get_path(&modules.bevy_asset);
let field_attributes = get_field_attributes::<UniformAttributes, UniformAttributeArgs>(
UNIFORM_ATTRIBUTE_NAME,
&ast.data,
);
let struct_name = &ast.ident;
let mut active_uniform_field_names = Vec::new();
let mut active_uniform_field_name_strings = Vec::new();
let mut uniform_name_strings = Vec::new();
let mut texture_and_sampler_name_strings = Vec::new();
let mut texture_and_sampler_name_idents = Vec::new();
let mut field_infos = Vec::new();
let mut get_field_bind_types = Vec::new();
let mut shader_def_field_names = Vec::new();
let mut shader_def_field_names_screaming_snake = Vec::new();
for (f, attrs) in field_attributes.iter() {
let field_name = f.ident.as_ref().unwrap().to_string();
if !attrs.ignore {
let active_uniform_field_name = &f.ident;
active_uniform_field_names.push(&f.ident);
active_uniform_field_name_strings.push(field_name.clone());
let uniform = format!("{}_{}", struct_name, field_name);
let texture = format!("{}", uniform);
let sampler = format!("{}_sampler", uniform);
uniform_name_strings.push(uniform.clone());
texture_and_sampler_name_strings.push(texture.clone());
texture_and_sampler_name_strings.push(sampler.clone());
texture_and_sampler_name_idents.push(f.ident.clone());
texture_and_sampler_name_idents.push(f.ident.clone());
field_infos.push(quote!(#bevy_render_path::shader::FieldInfo {
name: #field_name,
uniform_name: #uniform,
texture_name: #texture,
sampler_name: #sampler,
}));
if attrs.buffer {
get_field_bind_types.push(quote!({
let bind_type = self.#active_uniform_field_name.get_bind_type();
let size = if let Some(#bevy_render_path::shader::FieldBindType::Uniform { size }) = bind_type {
size
} else {
panic!("Uniform field was labeled as a 'buffer', but it does not have a compatible type.")
};
Some(#bevy_render_path::shader::FieldBindType::Buffer { size })
}))
} else {
get_field_bind_types.push(quote!(self.#active_uniform_field_name.get_bind_type()))
}
}
if attrs.shader_def {
shader_def_field_names.push(&f.ident);
shader_def_field_names_screaming_snake.push(field_name.to_screaming_snake_case())
}
}
let struct_name_string = struct_name.to_string();
let struct_name_uppercase = struct_name_string.to_uppercase();
let field_infos_ident = format_ident!("{}_FIELD_INFO", struct_name_uppercase);
TokenStream::from(quote! {
static #field_infos_ident: &[#bevy_render_path::shader::FieldInfo] = &[
#(#field_infos,)*
];
impl #bevy_render_path::shader::Uniforms for #struct_name {
fn get_field_infos() -> &'static [#bevy_render_path::shader::FieldInfo] {
#field_infos_ident
}
fn get_field_bind_type(&self, name: &str) -> Option<#bevy_render_path::shader::FieldBindType> {
None
}
fn get_uniform_texture(&self, name: &str) -> Option<#bevy_asset_path::Handle<#bevy_render_path::texture::Texture>> {
None
}
fn write_uniform_bytes(&self, name: &str, buffer: &mut [u8]) {
use #bevy_core_path::bytes::Bytes;
}
fn uniform_byte_len(&self, name: &str) -> usize {
0
}
// TODO: move this to field_info and add has_shader_def(&self, &str) -> bool
// TODO: this will be very allocation heavy. find a way to either make this allocation free
// or alternatively only run it when the shader_defs have changed
fn get_shader_defs(&self) -> Option<Vec<String>> {
None
}
}
})
}
pub fn derive_uniform(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let modules = get_modules(&ast);
let bevy_asset_path = get_path(&modules.bevy_asset);
let bevy_render_path = get_path(&modules.bevy_render);
let generics = ast.generics;
let (impl_generics, ty_generics, _where_clause) = generics.split_for_impl();
let struct_name = &ast.ident;
let struct_name_string = struct_name.to_string();
TokenStream::from(quote! {
impl #impl_generics #bevy_render_path::shader::Uniforms for #struct_name#ty_generics {
fn get_field_infos() -> &'static [#bevy_render_path::shader::FieldInfo] {
static FIELD_INFOS: &[#bevy_render_path::shader::FieldInfo] = &[
#bevy_render_path::shader::FieldInfo {
name: #struct_name_string,
uniform_name: #struct_name_string,
texture_name: #struct_name_string,
sampler_name: #struct_name_string,
}
];
&FIELD_INFOS
}
fn get_field_bind_type(&self, name: &str) -> Option<#bevy_render_path::shader::FieldBindType> {
None
}
fn write_uniform_bytes(&self, name: &str, buffer: &mut [u8]) {
}
fn uniform_byte_len(&self, name: &str) -> usize {
0
}
fn get_uniform_texture(&self, name: &str) -> Option<#bevy_asset_path::Handle<#bevy_render_path::texture::Texture>> {
None
}
// TODO: move this to field_info and add has_shader_def(&self, &str) -> bool
// TODO: this will be very allocation heavy. find a way to either make this allocation free
// or alternatively only run it when the shader_defs have changed
fn get_shader_defs(&self) -> Option<Vec<String>> {
None
}
}
})
}

View File

@ -1,5 +1,5 @@
use super::texture::Texture;
use crate::{render_resource::{ResourceInfo, RenderResource}, shader::ShaderDefSuffixProvider, impl_render_resource_bytes};
use crate::{render_resource::{ResourceInfo, RenderResource}, impl_render_resource_bytes};
use bevy_asset::Handle;
use bevy_core::bytes::{Byteable, Bytes};
use bevy_property::Property;
@ -130,13 +130,4 @@ impl From<Handle<Texture>> for ColorSource {
}
}
impl ShaderDefSuffixProvider for ColorSource {
fn get_shader_def(&self) -> Option<&'static str> {
match *self {
ColorSource::Color(_) => Some("_COLOR"),
ColorSource::Texture(_) => Some("_TEXTURE"),
}
}
}
impl_render_resource_bytes!(Color);

View File

@ -431,7 +431,7 @@ pub fn mesh_resource_provider_system(resources: &mut Resources) -> Box<dyn Sched
#[cfg(test)]
mod tests {
use super::{Mesh, VertexAttribute, AsVertexBufferDescriptor};
use crate::{pipeline::state_descriptors::PrimitiveTopology, shader::Uniforms, Vertex};
use crate::{pipeline::state_descriptors::PrimitiveTopology, Vertex};
use bevy_core::bytes::AsBytes;
#[test]

View File

@ -202,7 +202,7 @@ impl RenderGraph {
});
}
if output_slot.info.resource_type != input_slot.info.resource_type {
if output_slot.info.resource_info != input_slot.info.resource_info {
return Err(RenderGraphError::MismatchedNodeSlots {
output_node,
output_slot: output_index,
@ -309,8 +309,7 @@ mod tests {
use super::RenderGraph;
use crate::{
render_graph::{Edge, Node, NodeId, RenderGraphError, ResourceSlotInfo, ResourceSlots},
renderer::RenderContext,
shader::FieldBindType,
renderer::RenderContext, render_resource::ResourceInfo,
};
use legion::prelude::{Resources, World};
use std::{collections::HashSet, iter::FromIterator};
@ -327,13 +326,13 @@ mod tests {
inputs: (0..inputs)
.map(|i| ResourceSlotInfo {
name: format!("in_{}", i).into(),
resource_type: FieldBindType::Texture,
resource_info: ResourceInfo::Texture(None),
})
.collect(),
outputs: (0..outputs)
.map(|i| ResourceSlotInfo {
name: format!("out_{}", i).into(),
resource_type: FieldBindType::Texture,
resource_info: ResourceInfo::Texture(None),
})
.collect(),
}

View File

@ -1,5 +1,5 @@
use super::RenderGraphError;
use crate::{render_resource::RenderResourceId, shader::FieldBindType};
use crate::render_resource::{RenderResourceId, ResourceInfo};
use std::borrow::Cow;
#[derive(Debug, Clone)]
@ -122,14 +122,14 @@ impl From<&[ResourceSlotInfo]> for ResourceSlots {
#[derive(Clone, Debug)]
pub struct ResourceSlotInfo {
pub name: Cow<'static, str>,
pub resource_type: FieldBindType,
pub resource_info: ResourceInfo,
}
impl ResourceSlotInfo {
pub fn new(name: impl Into<Cow<'static, str>>, resource_type: FieldBindType) -> Self {
pub fn new(name: impl Into<Cow<'static, str>>, resource_info: ResourceInfo) -> Self {
ResourceSlotInfo {
name: name.into(),
resource_type,
resource_info,
}
}
}

View File

@ -3,9 +3,9 @@ use crate::{
pass::{PassDescriptor, TextureAttachment},
pipeline::{PipelineCompiler, PipelineDescriptor},
render_graph::{Node, ResourceSlotInfo, ResourceSlots},
render_resource::RenderResourceAssignments,
render_resource::{ResourceInfo, RenderResourceAssignments},
renderer::RenderContext,
shader::{FieldBindType, Shader},
shader::Shader,
};
use bevy_asset::{Assets, Handle};
use legion::prelude::*;
@ -26,7 +26,7 @@ impl PassNode {
if let TextureAttachment::Input(ref name) = color_attachment.attachment {
inputs.push(ResourceSlotInfo::new(
name.to_string(),
FieldBindType::Texture,
ResourceInfo::Texture(None),
));
color_attachment_input_indices.push(Some(inputs.len() - 1));
} else {
@ -39,7 +39,7 @@ impl PassNode {
if let TextureAttachment::Input(ref name) = depth_stencil_attachment.attachment {
inputs.push(ResourceSlotInfo::new(
name.to_string(),
FieldBindType::Texture,
ResourceInfo::Texture(None),
));
depth_stencil_attachment_input_index = Some(inputs.len() - 1);
}

View File

@ -1,7 +1,7 @@
use crate::{
render_graph::{Node, ResourceSlotInfo, ResourceSlots},
render_resource::ResourceInfo,
renderer::RenderContext,
shader::FieldBindType,
};
use bevy_app::{EventReader, Events};
use bevy_window::{WindowCreated, WindowReference, WindowResized, Windows};
@ -16,9 +16,7 @@ pub struct WindowSwapChainNode {
impl WindowSwapChainNode {
pub const OUT_TEXTURE: &'static str = "texture";
pub fn new(
window_reference: WindowReference,
) -> Self {
pub fn new(window_reference: WindowReference) -> Self {
WindowSwapChainNode {
window_reference,
window_created_event_reader: Default::default(),
@ -31,7 +29,7 @@ impl Node for WindowSwapChainNode {
fn output(&self) -> &[ResourceSlotInfo] {
static OUTPUT: &[ResourceSlotInfo] = &[ResourceSlotInfo {
name: Cow::Borrowed(WindowSwapChainNode::OUT_TEXTURE),
resource_type: FieldBindType::Texture,
resource_info: ResourceInfo::Texture(None),
}];
OUTPUT
}

View File

@ -1,7 +1,7 @@
use crate::{
render_graph::{Node, ResourceSlotInfo, ResourceSlots},
render_resource::ResourceInfo,
renderer::RenderContext,
shader::FieldBindType,
texture::TextureDescriptor,
};
use bevy_app::{EventReader, Events};
@ -18,10 +18,7 @@ pub struct WindowTextureNode {
impl WindowTextureNode {
pub const OUT_TEXTURE: &'static str = "texture";
pub fn new(
window_reference: WindowReference,
descriptor: TextureDescriptor,
) -> Self {
pub fn new(window_reference: WindowReference, descriptor: TextureDescriptor) -> Self {
WindowTextureNode {
window_reference,
descriptor,
@ -35,7 +32,7 @@ impl Node for WindowTextureNode {
fn output(&self) -> &[ResourceSlotInfo] {
static OUTPUT: &[ResourceSlotInfo] = &[ResourceSlotInfo {
name: Cow::Borrowed(WindowTextureNode::OUT_TEXTURE),
resource_type: FieldBindType::Texture,
resource_info: ResourceInfo::Texture(None),
}];
OUTPUT
}

View File

@ -264,8 +264,8 @@ mod tests {
use super::{DependentNodeStager, OrderedJob, RenderGraphStager, Stage};
use crate::{
render_graph::{Node, NodeId, RenderGraph, ResourceSlotInfo, ResourceSlots},
render_resource::ResourceInfo,
renderer::RenderContext,
shader::FieldBindType,
};
use legion::prelude::{Resources, World};
@ -280,13 +280,13 @@ mod tests {
inputs: (0..inputs)
.map(|i| ResourceSlotInfo {
name: format!("in_{}", i).into(),
resource_type: FieldBindType::Texture,
resource_info: ResourceInfo::Texture(None),
})
.collect(),
outputs: (0..outputs)
.map(|i| ResourceSlotInfo {
name: format!("out_{}", i).into(),
resource_type: FieldBindType::Texture,
resource_info: ResourceInfo::Texture(None),
})
.collect(),
}

View File

@ -113,3 +113,29 @@ where
None
}
}
impl RenderResources for bevy_transform::prelude::Transform {
fn render_resources_len(&self) -> usize {
1
}
fn get_render_resource(&self, index: usize) -> Option<&dyn RenderResource> {
if index == 0 {
Some(&self.value)
} else {
None
}
}
fn get_render_resource_name(&self, index: usize) -> Option<&str> {
if index == 0 {
Some("Transform")
} else {
None
}
}
fn iter_render_resources(&self) -> RenderResourceIterator {
RenderResourceIterator::new(self)
}
}

View File

@ -1,10 +1,7 @@
mod shader;
mod shader_defs;
mod shader_reflect;
mod uniform;
pub mod uniforms;
pub use shader::*;
pub use shader_defs::*;
pub use shader_reflect::*;
pub use uniform::*;

View File

@ -1,45 +0,0 @@
use crate::{pipeline::BindType, texture::Texture};
use bevy_asset::Handle;
pub use bevy_derive::{Uniform, Uniforms};
pub trait Uniforms: Send + Sync + 'static {
fn get_field_infos() -> &'static [FieldInfo];
fn write_uniform_bytes(&self, name: &str, buffer: &mut [u8]);
fn uniform_byte_len(&self, name: &str) -> usize;
fn get_uniform_texture(&self, name: &str) -> Option<Handle<Texture>>;
fn get_shader_defs(&self) -> Option<Vec<String>>;
fn get_field_bind_type(&self, name: &str) -> Option<FieldBindType>;
}
pub trait ShaderDefSuffixProvider {
fn get_shader_def(&self) -> Option<&'static str>;
}
impl ShaderDefSuffixProvider for bool {
fn get_shader_def(&self) -> Option<&'static str> {
match *self {
true => Some(""),
false => None,
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum FieldBindType {
Uniform { size: usize },
Buffer { size: usize },
Texture,
}
pub struct FieldInfo {
pub name: &'static str,
pub uniform_name: &'static str,
pub texture_name: &'static str,
pub sampler_name: &'static str,
}
pub struct UniformInfo<'a> {
pub name: &'a str,
pub bind_type: BindType,
}

View File

@ -1,27 +0,0 @@
use crate::render_resource::{RenderResource, RenderResourceIterator, RenderResources};
impl RenderResources for bevy_transform::prelude::Transform {
fn render_resources_len(&self) -> usize {
1
}
fn get_render_resource(&self, index: usize) -> Option<&dyn RenderResource> {
if index == 0 {
Some(&self.value)
} else {
None
}
}
fn get_render_resource_name(&self, index: usize) -> Option<&str> {
if index == 0 {
Some("Transform")
} else {
None
}
}
fn iter_render_resources(&self) -> RenderResourceIterator {
RenderResourceIterator::new(self)
}
}

View File

@ -1,7 +1,7 @@
use super::{SamplerDescriptor, TextureDescriptor};
use crate::{
renderer::{RenderResourceContext, RenderResources},
shader::ShaderDefSuffixProvider, render_resource::{ResourceInfo, RenderResource},
render_resource::{ResourceInfo, RenderResource},
};
use bevy_app::{EventReader, Events};
use bevy_asset::{AssetEvent, Assets, Handle};
@ -113,15 +113,6 @@ pub struct TextureResourceSystemState {
event_reader: EventReader<AssetEvent<Texture>>,
}
impl ShaderDefSuffixProvider for Option<Handle<Texture>> {
fn get_shader_def(&self) -> Option<&'static str> {
match *self {
Some(_) => Some(""),
None => None,
}
}
}
impl RenderResource for Option<Handle<Texture>> {
fn resource_info(&self) -> Option<ResourceInfo> {
self.map(|_texture| ResourceInfo::Texture(None))

View File

@ -1,8 +1,8 @@
use glam::Vec2;
use bevy_render::{shader::Uniform, render_resource::{RenderResources, RenderResource}};
use bevy_core::bytes::Bytes;
use bevy_render::render_resource::{RenderResource, RenderResources};
use glam::Vec2;
#[repr(C)]
#[derive(Default, Clone, Copy, Debug, Uniform, RenderResources, RenderResource, Bytes)]
#[derive(Default, Clone, Copy, Debug, RenderResources, RenderResource, Bytes)]
#[render_resources(from_self)]
pub struct Quad {
pub position: Vec2,

View File

@ -26,9 +26,7 @@ pub use crate::{
RenderGraph,
},
render_resource::RenderResources,
shader::{
Shader, ShaderDefSuffixProvider, ShaderDefs, ShaderStage, ShaderStages, Uniforms,
},
shader::{Shader, ShaderDefs, ShaderStage, ShaderStages},
texture::Texture,
Camera, Color, ColorSource, OrthographicProjection, PerspectiveProjection, Renderable,
},