mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
finish uniform names refactor
This commit is contained in:
parent
ba1f48f743
commit
7eb99f3eb5
8 changed files with 99 additions and 67 deletions
|
@ -45,6 +45,10 @@ See our [ROADMAP.md](ROADMAP.md) for the current list of planned features.
|
|||
|
||||
## Getting Started
|
||||
|
||||
### Nightly Compiler
|
||||
|
||||
Bevy requires nightly rust right now. It currently uses [specialization](https://github.com/rust-lang/rfcs/blob/master/text/1210-impl-specialization.md) features, which are unstable. If specialization goes stable soon then we can go back to a stable compiler. In the meantime, we will try our best to remove specialization usage so we can go back to stable.
|
||||
|
||||
### Examples:
|
||||
|
||||
```
|
||||
|
@ -53,7 +57,7 @@ cargo run --example simple
|
|||
|
||||
### Fast Compiles
|
||||
|
||||
* Bevy can be built using stable rust with default configuration (ex: ```cargo build```), but for optimal build times we recommend using a nightly compiler with the following settings:
|
||||
* Bevy can be built using default configuration (ex: ```cargo build```), but for optimal build times we recommend using a nightly compiler with the following settings:
|
||||
* LLD Linker: ```-Clink-arg=-fuse-ld=lld```
|
||||
* LLD will significantly speed up compile times in Bevy, but it doesn't work out of the box on some platforms / os-es.
|
||||
* See [this issue](https://github.com/rust-lang/rust/issues/39915) and [this issue](https://github.com/rust-gamedev/wg/issues/50) for more information.
|
||||
|
|
|
@ -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, Type};
|
||||
use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Field, Fields};
|
||||
|
||||
#[proc_macro_derive(EntityArchetype)]
|
||||
pub fn derive_entity_archetype(input: TokenStream) -> TokenStream {
|
||||
|
@ -108,22 +108,22 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
|
|||
|
||||
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 field_uniform_names_ident = format_ident!("{}_FIELD_UNIFORM_NAMES", struct_name_screaming_snake);
|
||||
|
||||
let active_uniform_field_names = active_uniform_fields.iter().map(|field| {
|
||||
&field.ident
|
||||
});
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
let active_uniform_field_name_strings = active_uniform_fields.iter().map(|field| {
|
||||
field.ident.as_ref().unwrap().to_string()
|
||||
}).collect::<Vec<String>>();
|
||||
|
||||
|
||||
let mut uniform_name_strings = Vec::new();
|
||||
let field_uniform_names = active_uniform_field_name_strings.iter().map(|f| {
|
||||
let uniform = format!("{}_{}", struct_name, f);
|
||||
let texture = format!("{}_texture", uniform);
|
||||
let sampler = format!("{}_sampler", uniform);
|
||||
uniform_name_strings.push(uniform.clone());
|
||||
quote!(bevy::render::render_graph::FieldUniformName {
|
||||
field: #f,
|
||||
uniform: #uniform,
|
||||
|
@ -132,21 +132,21 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
|
|||
})
|
||||
});
|
||||
|
||||
|
||||
let x = quote! {
|
||||
TokenStream::from(quote! {
|
||||
const #field_uniform_names_ident: &[bevy::render::render_graph::FieldUniformName] = &[
|
||||
#(#field_uniform_names,)*
|
||||
];
|
||||
|
||||
impl bevy::render::render_graph::AsUniforms for #struct_name {
|
||||
// TODO: max this an iterator that feeds on field_uniform_names_ident
|
||||
fn get_uniform_infos(&self) -> &[bevy::render::render_graph::FieldUniformName] {
|
||||
fn get_field_uniform_names(&self) -> &[bevy::render::render_graph::FieldUniformName] {
|
||||
#field_uniform_names_ident
|
||||
}
|
||||
|
||||
fn get_field_bind_type(&self, name: &str) -> Option<bevy::render::render_graph::FieldBindType> {
|
||||
use bevy::render::render_graph::AsFieldBindType;
|
||||
match name {
|
||||
#(#active_uniform_field_name_strings => #active_uniform_field_names.get_field_bind_type(),)*
|
||||
#(#active_uniform_field_name_strings => Some(self.#active_uniform_field_names.get_field_bind_type()),)*
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
|
|||
fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>> {
|
||||
use bevy::core::bytes::GetBytes;
|
||||
match name {
|
||||
// #(#uniform_name_uniform_info => Some(self.#get_uniform_bytes_field_name.get_bytes()),)*
|
||||
#(#uniform_name_strings => Some(self.#active_uniform_field_names.get_bytes()),)*
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -174,9 +174,7 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
|
|||
.collect::<Vec<String>>())
|
||||
}
|
||||
}
|
||||
};
|
||||
eprintln!("{}", x.to_string());
|
||||
TokenStream::from(x)
|
||||
})
|
||||
}
|
||||
|
||||
#[proc_macro_derive(RegisterAppPlugin)]
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use crate::{
|
||||
asset::{Texture, Handle},
|
||||
math::Vec4,
|
||||
};
|
||||
use zerocopy::AsBytes;
|
||||
use crate::math::Vec4;
|
||||
|
||||
pub trait GetBytes {
|
||||
fn get_bytes(&self) -> Vec<u8>;
|
||||
|
@ -27,3 +30,13 @@ impl GetBytes for Vec4 {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl GetBytes for Handle<Texture> {
|
||||
fn get_bytes(&self) -> Vec<u8> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn get_bytes_ref(&self) -> Option<&[u8]> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#![feature(specialization)]
|
||||
pub mod app;
|
||||
pub mod asset;
|
||||
pub mod core;
|
||||
|
|
|
@ -30,7 +30,6 @@ impl ShaderDefSuffixProvider for ColorSource {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
impl GetBytes for ColorSource {
|
||||
fn get_bytes(&self) -> Vec<u8> {
|
||||
match *self {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::render::render_graph::{
|
||||
AsUniforms, BindType, DynamicUniformBufferInfo, Renderable, Renderer, ResourceProvider,
|
||||
UniformInfoIter,
|
||||
};
|
||||
use legion::prelude::*;
|
||||
use std::marker::PhantomData;
|
||||
use std::{marker::PhantomData, ops::Deref};
|
||||
|
||||
pub struct UniformResourceProvider<T>
|
||||
where
|
||||
|
@ -48,9 +49,8 @@ where
|
|||
|
||||
let mut counts = Vec::new();
|
||||
for (uniforms, _renderable) in query.iter(world) {
|
||||
for (i, uniform_info) in uniforms
|
||||
.get_uniform_infos()
|
||||
.iter()
|
||||
let field_uniform_names = uniforms.get_field_uniform_names();
|
||||
for (i, uniform_info) in UniformInfoIter::new(field_uniform_names, uniforms.deref())
|
||||
.filter(|u| {
|
||||
if let BindType::Uniform { .. } = u.bind_type {
|
||||
true
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
use crate::render::{color::ColorSource, render_graph::{BindType, TextureViewDimension}};
|
||||
use crate::{
|
||||
math::Vec4,
|
||||
render::{
|
||||
color::ColorSource,
|
||||
render_graph::{BindType, TextureViewDimension},
|
||||
}, core::GetBytes,
|
||||
};
|
||||
use legion::prelude::Entity;
|
||||
use std::collections::HashMap;
|
||||
|
||||
// TODO: add ability to specify specific pipeline for uniforms
|
||||
pub trait AsUniforms {
|
||||
fn get_uniform_infos(&self) -> &[FieldUniformName];
|
||||
fn get_field_uniform_names(&self) -> &[FieldUniformName];
|
||||
fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>>;
|
||||
fn get_shader_defs(&self) -> Option<Vec<String>>;
|
||||
fn get_field_bind_type(&self, name: &str) -> Option<FieldBindType>;
|
||||
|
@ -30,27 +36,31 @@ pub enum FieldBindType {
|
|||
Texture,
|
||||
}
|
||||
|
||||
pub struct UniformInfoIter<'a, T: AsUniforms> {
|
||||
pub struct UniformInfoIter<'a, 'b, T: AsUniforms> {
|
||||
pub field_uniform_names: &'a [FieldUniformName],
|
||||
pub uniforms: &'a T,
|
||||
pub uniforms: &'b 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, 'b, T> UniformInfoIter<'a, 'b, T>
|
||||
where
|
||||
T: AsUniforms,
|
||||
{
|
||||
pub fn new(field_uniform_names: &'a [FieldUniformName], uniforms: &'b T) -> Self {
|
||||
UniformInfoIter {
|
||||
field_uniform_names,
|
||||
uniforms,
|
||||
index: 0,
|
||||
add_sampler: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for UniformInfoIter<'a, T> where T: AsUniforms {
|
||||
impl<'a, 'b, T> Iterator for UniformInfoIter<'a, 'b, T>
|
||||
where
|
||||
T: AsUniforms,
|
||||
{
|
||||
type Item = UniformInfo<'a>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.add_sampler {
|
||||
|
@ -65,8 +75,11 @@ impl<'a, T> Iterator for UniformInfoIter<'a, T> where T: AsUniforms {
|
|||
} 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();
|
||||
let ref 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 {
|
||||
|
@ -89,22 +102,21 @@ impl<'a, T> Iterator for UniformInfoIter<'a, T> where T: AsUniforms {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub struct FieldUniformName {
|
||||
field: &'static str,
|
||||
uniform: &'static str,
|
||||
texture: &'static str,
|
||||
sampler: &'static str,
|
||||
pub field: &'static str,
|
||||
pub uniform: &'static str,
|
||||
pub texture: &'static str,
|
||||
pub sampler: &'static str,
|
||||
}
|
||||
|
||||
pub trait AsFieldBindType {
|
||||
fn get_field_uniform_type(&self) -> FieldBindType;
|
||||
fn get_field_bind_type(&self) -> FieldBindType;
|
||||
}
|
||||
|
||||
impl AsFieldBindType for ColorSource {
|
||||
fn get_field_uniform_type(&self) -> FieldBindType {
|
||||
fn get_field_bind_type(&self) -> FieldBindType {
|
||||
match *self {
|
||||
ColorSource::Texture(_) => FieldBindType::Texture,
|
||||
ColorSource::Color(_) => FieldBindType::Uniform,
|
||||
|
@ -112,14 +124,21 @@ impl AsFieldBindType for ColorSource {
|
|||
}
|
||||
}
|
||||
|
||||
// impl<T> AsFieldBindType for T
|
||||
// where
|
||||
// T: GetBytes,
|
||||
// {
|
||||
// fn get_field_uniform_type(&self) -> FieldBindType {
|
||||
// FieldBindType::Uniform
|
||||
// }
|
||||
// }
|
||||
default impl<T> AsFieldBindType for T
|
||||
where
|
||||
T: GetBytes,
|
||||
{
|
||||
fn get_field_bind_type(&self) -> FieldBindType {
|
||||
FieldBindType::Uniform
|
||||
}
|
||||
}
|
||||
|
||||
impl AsFieldBindType for Vec4
|
||||
{
|
||||
fn get_field_bind_type(&self) -> FieldBindType {
|
||||
FieldBindType::Uniform
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UniformInfo<'a> {
|
||||
pub name: &'a str,
|
||||
|
@ -142,4 +161,4 @@ impl DynamicUniformBufferInfo {
|
|||
offsets: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +1,17 @@
|
|||
use crate::render::render_graph::{
|
||||
uniform::{AsUniforms, UniformInfo},
|
||||
BindType, FieldBindType,
|
||||
};
|
||||
use crate::render::render_graph::{uniform::AsUniforms, FieldBindType, FieldUniformName};
|
||||
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
const LOCAL_TO_WORLD_UNIFORM_INFO: &[UniformInfo] = &[UniformInfo {
|
||||
name: "Object",
|
||||
bind_type: BindType::Uniform {
|
||||
dynamic: false,
|
||||
// TODO: maybe fill this in with properties (vec.push cant be const though)
|
||||
properties: Vec::new(),
|
||||
},
|
||||
const LOCAL_TO_WORLD_FIELD_UNIFORM_NAMES: &[FieldUniformName] = &[FieldUniformName {
|
||||
field: "object",
|
||||
uniform: "Object",
|
||||
texture: "",
|
||||
sampler: "",
|
||||
}];
|
||||
|
||||
impl AsUniforms for bevy_transform::prelude::LocalToWorld {
|
||||
fn get_uniform_infos(&self) -> &[UniformInfo] {
|
||||
LOCAL_TO_WORLD_UNIFORM_INFO
|
||||
fn get_field_uniform_names(&self) -> &[FieldUniformName] {
|
||||
LOCAL_TO_WORLD_FIELD_UNIFORM_NAMES
|
||||
}
|
||||
|
||||
fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>> {
|
||||
|
@ -29,7 +24,10 @@ impl AsUniforms for bevy_transform::prelude::LocalToWorld {
|
|||
fn get_shader_defs(&self) -> Option<Vec<String>> {
|
||||
None
|
||||
}
|
||||
fn get_field_bind_type(&self, name: &str) -> FieldBindType {
|
||||
FieldBindType::Uniform
|
||||
fn get_field_bind_type(&self, name: &str) -> Option<FieldBindType> {
|
||||
match name {
|
||||
"object" => Some(FieldBindType::Uniform),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue