reorganize render modules

This commit is contained in:
Carter Anderson 2020-03-09 23:08:09 -07:00
parent ccb240c4c4
commit aa09e93980
71 changed files with 617 additions and 547 deletions

View file

@ -131,7 +131,7 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
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());
quote!(bevy::render::render_graph::FieldUniformName {
quote!(bevy::render::shader::FieldUniformName {
field: #field_name,
uniform: #uniform,
texture: #texture,
@ -140,18 +140,18 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
});
TokenStream::from(quote! {
const #field_uniform_names_ident: &[bevy::render::render_graph::FieldUniformName] = &[
const #field_uniform_names_ident: &[bevy::render::shader::FieldUniformName] = &[
#(#field_uniform_names,)*
];
impl bevy::render::render_graph::AsUniforms for #struct_name {
impl bevy::render::shader::AsUniforms for #struct_name {
// TODO: max this an iterator that feeds on field_uniform_names_ident
fn get_field_uniform_names(&self) -> &[bevy::render::render_graph::FieldUniformName] {
fn get_field_uniform_names(&self) -> &[bevy::render::shader::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;
fn get_field_bind_type(&self, name: &str) -> Option<bevy::render::shader::FieldBindType> {
use bevy::render::shader::AsFieldBindType;
match name {
#(#active_uniform_field_name_strings => Some(self.#active_uniform_field_names.get_field_bind_type()),)*
_ => None,
@ -168,7 +168,7 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
}
fn get_uniform_texture(&self, name: &str) -> Option<bevy::asset::Handle<bevy::asset::Texture>> {
use bevy::render::render_graph::GetTexture;
use bevy::render::shader::GetTexture;
match name {
#(#texture_and_sampler_name_strings => self.#texture_and_sampler_name_idents.get_texture(),)*
_ => None,
@ -178,7 +178,7 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
// 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>> {
use bevy::render::render_graph::ShaderDefSuffixProvider;
use bevy::render::shader::ShaderDefSuffixProvider;
let mut potential_shader_defs: Vec<(&'static str, Option<&'static str>)> = vec![
#((#shader_def_field_names_screaming_snake, self.#shader_def_field_names.get_shader_def()),)*
];

View file

@ -1,12 +1,4 @@
use bevy::{
prelude::*,
render::{
render_graph::{
resource_name, resource_providers::UniformResourceProvider, PipelineDescriptor,
},
Shader, ShaderStage,
},
};
use bevy::prelude::*;
use bevy_derive::Uniforms;

View file

@ -9,7 +9,7 @@ use legion::prelude::*;
use crate::{
app::AppBuilder,
core::Time,
render::render_graph::{RenderGraph, Renderer},
render::{render_graph::RenderGraph, renderer::Renderer},
};
pub struct App {

View file

@ -4,18 +4,22 @@ use crate::{
core::Time,
legion::prelude::{Resources, Runnable, Schedulable, Schedule, Universe, World},
plugin::load_plugin,
prelude::StandardMaterial,
render::{
render_graph::{
draw_targets::*, passes::*, pipelines::*, renderers::wgpu_renderer::WgpuRenderer,
resource_providers::*, CompiledShaderMap, PipelineDescriptor, RenderGraphBuilder,
Renderer, ShaderPipelineAssignments, StandardMaterial,
},
draw_target::draw_targets::*,
pass::passes::*,
pipeline::pipelines::*,
render_resource::resource_providers::*,
renderer::{renderers::wgpu_renderer::WgpuRenderer, Renderer},
*,
},
ui,
};
use bevy_transform::{prelude::LocalToWorld, transform_system_bundle};
use pipeline::PipelineDescriptor;
use render_graph::RenderGraphBuilder;
use shader::Shader;
use std::collections::HashMap;
pub struct AppBuilder {

View file

@ -1,7 +1,4 @@
use crate::{
asset::Asset,
render::render_graph::{TextureDescriptor, TextureDimension},
};
use crate::asset::Asset;
use std::fs::File;
pub enum TextureType {
@ -36,24 +33,6 @@ impl Asset<TextureType> for Texture {
}
}
impl From<&Texture> for TextureDescriptor {
fn from(texture: &Texture) -> Self {
TextureDescriptor {
size: wgpu::Extent3d {
height: texture.height as u32,
width: texture.width as u32,
depth: 1,
},
array_layer_count: 1,
mip_level_count: 1,
sample_count: 1,
dimension: TextureDimension::D2,
format: wgpu::TextureFormat::Rgba8UnormSrgb,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
}
}
}
pub fn create_texels(size: usize) -> Vec<u8> {
use std::iter;

View file

@ -1,7 +1,4 @@
use crate::{
prelude::*,
render::render_graph::{Renderable, StandardMaterial},
};
use crate::{prelude::*, render::Renderable};
use crate as bevy; // for macro imports
use bevy_derive::EntityArchetype;

View file

@ -5,8 +5,11 @@ pub use crate::{
ecs,
ecs::{default_archetypes::*, EntityArchetype, WorldBuilder, WorldBuilderSource},
render::{
render_graph::{Renderable, ShaderDefSuffixProvider, StandardMaterial},
pipeline::PipelineDescriptor,
render_resource::{resource_name, resource_providers::UniformResourceProvider},
shader::{uniforms::StandardMaterial, Shader, ShaderDefSuffixProvider, ShaderStage},
ActiveCamera, ActiveCamera2d, Camera, CameraType, ColorSource, Instanced, Light,
Renderable,
},
ui::{Anchors, Margins, Node},
};

View file

@ -2,7 +2,7 @@ use crate::{
asset::{Handle, Texture},
core::GetBytes,
math::Vec4,
render::render_graph::ShaderDefSuffixProvider,
render::shader::ShaderDefSuffixProvider,
};
pub enum ColorSource {

View file

@ -1,7 +1,9 @@
use super::Renderer;
use crate::{
asset::Handle,
render::render_graph::{pipeline::PipelineDescriptor, RenderPass},
render::{
pipeline::PipelineDescriptor,
renderer::{RenderPass, Renderer},
},
};
use legion::prelude::{Resources, World};

View file

@ -1,9 +1,12 @@
use crate::{
asset::{AssetStorage, Handle, Mesh},
legion::prelude::*,
render::render_graph::{
resource_name, DrawTarget, PipelineDescriptor, RenderPass, Renderable, ResourceInfo,
ShaderPipelineAssignments,
render::{
draw_target::DrawTarget,
pipeline::PipelineDescriptor,
render_resource::{resource_name, ResourceInfo},
renderer::{RenderPass, Renderer},
Renderable, ShaderPipelineAssignments,
},
};
@ -67,7 +70,7 @@ impl DrawTarget for AssignedMeshesDrawTarget {
&mut self,
world: &World,
resources: &Resources,
renderer: &mut dyn crate::render::render_graph::Renderer,
renderer: &mut dyn Renderer,
pipeline_handle: Handle<PipelineDescriptor>,
) {
let shader_pipeline_assignments = resources.get::<ShaderPipelineAssignments>().unwrap();

View file

@ -2,10 +2,11 @@ use crate::{
asset::{Handle, Mesh},
legion::prelude::*,
render::{
render_graph::{
resource_name, DrawTarget, PipelineDescriptor, RenderPass, Renderable, ResourceInfo,
},
Instanced,
draw_target::DrawTarget,
pipeline::PipelineDescriptor,
render_resource::{resource_name, ResourceInfo},
renderer::{RenderPass, Renderer},
Instanced, Renderable,
},
};
@ -61,7 +62,7 @@ impl DrawTarget for MeshesDrawTarget {
&mut self,
_world: &World,
_resources: &Resources,
_renderer: &mut dyn crate::render::render_graph::Renderer,
_renderer: &mut dyn Renderer,
_pipeline_handle: Handle<PipelineDescriptor>,
) {
}

View file

@ -1,8 +1,11 @@
use crate::{
asset::{AssetStorage, Handle, Mesh},
legion::prelude::*,
render::render_graph::{
resource_name, DrawTarget, PipelineDescriptor, RenderPass, RenderResource, ResourceInfo,
render::{
draw_target::DrawTarget,
pipeline::PipelineDescriptor,
render_resource::{resource_name, RenderResource, ResourceInfo},
renderer::{RenderPass, Renderer},
},
};
@ -59,7 +62,7 @@ impl DrawTarget for UiDrawTarget {
&mut self,
_world: &World,
resources: &Resources,
renderer: &mut dyn crate::render::render_graph::Renderer,
renderer: &mut dyn Renderer,
_pipeline_handle: Handle<PipelineDescriptor>,
) {
// don't create meshes if they have already been created

View file

@ -0,0 +1,4 @@
mod draw_target;
pub mod draw_targets;
pub use draw_target::*;

View file

@ -1,7 +1,6 @@
pub mod camera;
pub mod render_graph;
pub mod shader;
pub mod shader_reflect;
mod color;
mod light;
@ -10,8 +9,16 @@ mod vertex;
pub use camera::*;
pub use color::*;
pub use light::*;
pub use shader::*;
pub use renderable::*;
pub use vertex::Vertex;
pub mod draw_target;
pub mod pass;
pub mod pipeline;
pub mod render_resource;
mod renderable;
pub mod renderer;
pub mod texture;
pub struct Instanced;

4
src/render/pass/mod.rs Normal file
View file

@ -0,0 +1,4 @@
mod pass;
pub mod passes;
pub use pass::*;

View file

@ -1,7 +1,11 @@
use crate::render::render_graph::{
resource_name, resource_providers::FrameTextureResourceProvider, PassDescriptor,
RenderGraphBuilder, RenderPassColorAttachmentDescriptor,
RenderPassDepthStencilAttachmentDescriptor, TextureDescriptor, TextureDimension,
use crate::render::{
pass::{
PassDescriptor, RenderPassColorAttachmentDescriptor,
RenderPassDepthStencilAttachmentDescriptor,
},
render_graph::RenderGraphBuilder,
render_resource::{resource_name, resource_providers::FrameTextureResourceProvider},
texture::{TextureDescriptor, TextureDimension},
};
pub trait ForwardPassBuilder {

View file

@ -0,0 +1,55 @@
use super::Binding;
use std::{
collections::{hash_map::DefaultHasher, BTreeSet},
hash::{Hash, Hasher},
};
#[derive(Clone, Debug)]
pub struct BindGroup {
pub index: u32,
pub bindings: BTreeSet<Binding>,
hash: Option<u64>,
}
impl BindGroup {
pub fn new(index: u32, bindings: Vec<Binding>) -> Self {
BindGroup {
index,
bindings: bindings.iter().cloned().collect(),
hash: None,
}
}
pub fn get_hash(&self) -> Option<u64> {
self.hash
}
pub fn get_or_update_hash(&mut self) -> u64 {
if self.hash.is_none() {
self.update_hash();
}
self.hash.unwrap()
}
pub fn update_hash(&mut self) {
let mut hasher = DefaultHasher::new();
self.hash(&mut hasher);
self.hash = Some(hasher.finish());
}
}
impl Hash for BindGroup {
fn hash<H: Hasher>(&self, state: &mut H) {
self.index.hash(state);
self.bindings.hash(state);
}
}
impl PartialEq for BindGroup {
fn eq(&self, other: &BindGroup) -> bool {
self.index == other.index && self.bindings == other.bindings
}
}
impl Eq for BindGroup {}

View file

@ -0,0 +1,43 @@
use super::UniformProperty;
use crate::render::texture::TextureViewDimension;
#[derive(Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct Binding {
pub name: String,
pub index: u32,
pub bind_type: BindType,
// TODO: ADD SHADER STAGE VISIBILITY
}
#[derive(Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum BindType {
Uniform {
dynamic: bool,
properties: Vec<UniformProperty>,
},
Buffer {
dynamic: bool,
readonly: bool,
},
Sampler,
SampledTexture {
multisampled: bool,
dimension: TextureViewDimension,
},
StorageTexture {
dimension: TextureViewDimension,
},
}
impl BindType {
pub fn get_uniform_size(&self) -> Option<u64> {
match self {
BindType::Uniform { properties, .. } => {
Some(properties.iter().fold(0, |total, property| {
total + property.property_type.get_size()
}))
}
_ => None,
}
}
}

View file

@ -0,0 +1,10 @@
mod bind_group;
mod binding;
mod pipeline;
mod pipeline_layout;
pub mod pipelines;
pub use bind_group::*;
pub use binding::*;
pub use pipeline::*;
pub use pipeline_layout::*;

View file

@ -1,7 +1,8 @@
use super::{BindGroup, PipelineLayout};
use crate::{
asset::{AssetStorage, Handle},
render::{
render_graph::{resource_name, BindGroup, PipelineLayout},
render_resource::resource_name,
shader::{Shader, ShaderStages},
Vertex,
},

View file

@ -0,0 +1,93 @@
use super::BindGroup;
use crate::render::shader::ShaderLayout;
use std::{collections::HashMap, hash::Hash};
#[derive(Clone, Debug)]
pub struct PipelineLayout {
pub bind_groups: Vec<BindGroup>,
}
impl PipelineLayout {
pub fn new() -> Self {
PipelineLayout {
bind_groups: Vec::new(),
}
}
pub fn from_shader_layouts(shader_layouts: &mut [ShaderLayout]) -> Self {
let mut bind_groups = HashMap::<u32, BindGroup>::new();
for shader_layout in shader_layouts {
for shader_bind_group in shader_layout.bind_groups.iter_mut() {
match bind_groups.get_mut(&shader_bind_group.index) {
Some(bind_group) => {
for shader_binding in shader_bind_group.bindings.iter() {
if let Some(binding) = bind_group
.bindings
.iter()
.find(|binding| binding.index == shader_binding.index)
{
if binding != shader_binding {
panic!("Binding {} in BindGroup {} does not match across all shader types: {:?} {:?}", binding.index, bind_group.index, binding, shader_binding);
}
} else {
bind_group.bindings.insert(shader_binding.clone());
}
}
}
None => {
bind_groups.insert(shader_bind_group.index, shader_bind_group.clone());
}
}
}
}
let mut bind_groups_result = bind_groups
.drain()
.map(|(_, value)| value)
.collect::<Vec<BindGroup>>();
// NOTE: for some reason bind groups need to be sorted by index. this is likely an issue with bevy and not with wgpu
bind_groups_result.sort_by(|a, b| a.index.partial_cmp(&b.index).unwrap());
PipelineLayout {
bind_groups: bind_groups_result,
}
}
}
#[derive(Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct UniformProperty {
pub name: String,
pub property_type: UniformPropertyType,
}
#[derive(Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum UniformPropertyType {
// TODO: Add all types here
Int,
Float,
UVec4,
Vec3,
Vec4,
Mat3,
Mat4,
Struct(Vec<UniformProperty>),
Array(Box<UniformPropertyType>, usize),
}
impl UniformPropertyType {
pub fn get_size(&self) -> u64 {
match self {
UniformPropertyType::Int => 4,
UniformPropertyType::Float => 4,
UniformPropertyType::UVec4 => 4 * 4,
UniformPropertyType::Vec3 => 4 * 3,
UniformPropertyType::Vec4 => 4 * 4,
UniformPropertyType::Mat3 => 4 * 4 * 3,
UniformPropertyType::Mat4 => 4 * 4 * 4,
UniformPropertyType::Struct(properties) => properties
.iter()
.map(|p| p.property_type.get_size())
.fold(0, |total, size| total + size),
UniformPropertyType::Array(property, length) => property.get_size() * *length as u64,
}
}
}

View file

@ -1,7 +1,9 @@
use crate::{
asset::AssetStorage,
render::{
render_graph::{resource_name, PipelineDescriptor, RenderGraphBuilder},
pipeline::PipelineDescriptor,
render_graph::RenderGraphBuilder,
render_resource::resource_name,
shader::{Shader, ShaderStage},
Vertex,
},

View file

@ -1,7 +1,9 @@
use crate::{
asset::AssetStorage,
render::{
render_graph::{resource_name, PipelineDescriptor, RenderGraphBuilder},
pipeline::PipelineDescriptor,
render_graph::RenderGraphBuilder,
render_resource::resource_name,
shader::{Shader, ShaderStage},
Vertex,
},

View file

@ -1,10 +1,9 @@
use crate::{
asset::AssetStorage,
render::{
render_graph::{
resource_name, resource_providers::RectData, PipelineDescriptor, RenderGraphBuilder,
VertexBufferDescriptor,
},
pipeline::{PipelineDescriptor, VertexBufferDescriptor},
render_graph::RenderGraphBuilder,
render_resource::{resource_name, resource_providers::RectData},
shader::{Shader, ShaderStage},
Vertex,
},

View file

@ -1,31 +1,5 @@
mod draw_target;
pub mod draw_targets;
mod pass;
pub mod passes;
mod pipeline;
mod pipeline_layout;
pub mod pipelines;
mod render_graph;
mod render_resource;
mod renderable;
mod renderer;
pub mod renderers;
mod resource;
pub mod resource_name;
pub mod resource_provider;
pub mod resource_providers;
mod uniform;
mod uniforms;
mod render_graph_builder;
pub use draw_target::*;
pub use pass::*;
pub use pipeline::*;
pub use pipeline_layout::*;
pub use render_graph::*;
pub use render_resource::*;
pub use renderable::*;
pub use renderer::*;
pub use resource::*;
pub use resource_provider::*;
pub use uniform::*;
pub use uniforms::*;
pub use render_graph_builder::*;

View file

@ -1,296 +0,0 @@
use crate::{asset::Texture, render::shader_reflect::ShaderLayout};
use std::{
collections::{hash_map::DefaultHasher, BTreeSet, HashMap},
hash::{Hash, Hasher},
};
#[derive(Clone, Debug)]
pub struct PipelineLayout {
pub bind_groups: Vec<BindGroup>,
}
impl PipelineLayout {
pub fn new() -> Self {
PipelineLayout {
bind_groups: Vec::new(),
}
}
pub fn from_shader_layouts(shader_layouts: &mut [ShaderLayout]) -> Self {
let mut bind_groups = HashMap::<u32, BindGroup>::new();
for shader_layout in shader_layouts {
for shader_bind_group in shader_layout.bind_groups.iter_mut() {
match bind_groups.get_mut(&shader_bind_group.index) {
Some(bind_group) => {
for shader_binding in shader_bind_group.bindings.iter() {
if let Some(binding) = bind_group
.bindings
.iter()
.find(|binding| binding.index == shader_binding.index)
{
if binding != shader_binding {
panic!("Binding {} in BindGroup {} does not match across all shader types: {:?} {:?}", binding.index, bind_group.index, binding, shader_binding);
}
} else {
bind_group.bindings.insert(shader_binding.clone());
}
}
}
None => {
bind_groups.insert(shader_bind_group.index, shader_bind_group.clone());
}
}
}
}
let mut bind_groups_result = bind_groups
.drain()
.map(|(_, value)| value)
.collect::<Vec<BindGroup>>();
// NOTE: for some reason bind groups need to be sorted by index. this is likely an issue with bevy and not with wgpu
bind_groups_result.sort_by(|a, b| a.index.partial_cmp(&b.index).unwrap());
PipelineLayout {
bind_groups: bind_groups_result,
}
}
}
#[derive(Clone, Debug)]
pub struct BindGroup {
pub index: u32,
pub bindings: BTreeSet<Binding>,
hash: Option<u64>,
}
impl BindGroup {
pub fn new(index: u32, bindings: Vec<Binding>) -> Self {
BindGroup {
index,
bindings: bindings.iter().cloned().collect(),
hash: None,
}
}
pub fn get_hash(&self) -> Option<u64> {
self.hash
}
pub fn get_or_update_hash(&mut self) -> u64 {
if self.hash.is_none() {
self.update_hash();
}
self.hash.unwrap()
}
pub fn update_hash(&mut self) {
let mut hasher = DefaultHasher::new();
self.hash(&mut hasher);
self.hash = Some(hasher.finish());
}
}
impl Hash for BindGroup {
fn hash<H: Hasher>(&self, state: &mut H) {
self.index.hash(state);
self.bindings.hash(state);
}
}
impl PartialEq for BindGroup {
fn eq(&self, other: &BindGroup) -> bool {
self.index == other.index && self.bindings == other.bindings
}
}
impl Eq for BindGroup {}
#[derive(Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct Binding {
pub name: String,
pub index: u32,
pub bind_type: BindType,
// TODO: ADD SHADER STAGE VISIBILITY
}
#[derive(Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum BindType {
Uniform {
dynamic: bool,
properties: Vec<UniformProperty>,
},
Buffer {
dynamic: bool,
readonly: bool,
},
Sampler,
SampledTexture {
multisampled: bool,
dimension: TextureViewDimension,
},
StorageTexture {
dimension: TextureViewDimension,
},
}
impl BindType {
pub fn get_uniform_size(&self) -> Option<u64> {
match self {
BindType::Uniform { properties, .. } => {
Some(properties.iter().fold(0, |total, property| {
total + property.property_type.get_size()
}))
}
_ => None,
}
}
}
#[derive(Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct UniformProperty {
pub name: String,
pub property_type: UniformPropertyType,
}
#[derive(Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum UniformPropertyType {
// TODO: Add all types here
Int,
Float,
UVec4,
Vec3,
Vec4,
Mat3,
Mat4,
Struct(Vec<UniformProperty>),
Array(Box<UniformPropertyType>, usize),
}
impl UniformPropertyType {
pub fn get_size(&self) -> u64 {
match self {
UniformPropertyType::Int => 4,
UniformPropertyType::Float => 4,
UniformPropertyType::UVec4 => 4 * 4,
UniformPropertyType::Vec3 => 4 * 3,
UniformPropertyType::Vec4 => 4 * 4,
UniformPropertyType::Mat3 => 4 * 4 * 3,
UniformPropertyType::Mat4 => 4 * 4 * 4,
UniformPropertyType::Struct(properties) => properties
.iter()
.map(|p| p.property_type.get_size())
.fold(0, |total, size| total + size),
UniformPropertyType::Array(property, length) => property.get_size() * *length as u64,
}
}
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub enum TextureViewDimension {
D1,
D2,
D2Array,
Cube,
CubeArray,
D3,
}
impl From<TextureViewDimension> for wgpu::TextureViewDimension {
fn from(dimension: TextureViewDimension) -> Self {
match dimension {
TextureViewDimension::D1 => wgpu::TextureViewDimension::D1,
TextureViewDimension::D2 => wgpu::TextureViewDimension::D2,
TextureViewDimension::D2Array => wgpu::TextureViewDimension::D2Array,
TextureViewDimension::Cube => wgpu::TextureViewDimension::Cube,
TextureViewDimension::CubeArray => wgpu::TextureViewDimension::CubeArray,
TextureViewDimension::D3 => wgpu::TextureViewDimension::D3,
}
}
}
#[derive(Copy, Clone, Debug, Hash)]
pub enum TextureDimension {
D1,
D2,
D3,
}
impl From<TextureDimension> for wgpu::TextureDimension {
fn from(dimension: TextureDimension) -> Self {
match dimension {
TextureDimension::D1 => wgpu::TextureDimension::D1,
TextureDimension::D2 => wgpu::TextureDimension::D2,
TextureDimension::D3 => wgpu::TextureDimension::D3,
}
}
}
#[derive(Copy, Clone)]
pub struct TextureDescriptor {
pub size: wgpu::Extent3d,
pub array_layer_count: u32,
pub mip_level_count: u32,
pub sample_count: u32,
pub dimension: TextureDimension,
pub format: wgpu::TextureFormat,
pub usage: wgpu::TextureUsage,
}
impl From<TextureDescriptor> for wgpu::TextureDescriptor {
fn from(texture_descriptor: TextureDescriptor) -> Self {
wgpu::TextureDescriptor {
size: texture_descriptor.size,
array_layer_count: texture_descriptor.array_layer_count,
mip_level_count: texture_descriptor.mip_level_count,
sample_count: texture_descriptor.sample_count,
dimension: texture_descriptor.dimension.into(),
format: texture_descriptor.format,
usage: texture_descriptor.usage,
}
}
}
#[derive(Copy, Clone)]
pub struct SamplerDescriptor {
pub address_mode_u: wgpu::AddressMode,
pub address_mode_v: wgpu::AddressMode,
pub address_mode_w: wgpu::AddressMode,
pub mag_filter: wgpu::FilterMode,
pub min_filter: wgpu::FilterMode,
pub mipmap_filter: wgpu::FilterMode,
pub lod_min_clamp: f32,
pub lod_max_clamp: f32,
pub compare_function: wgpu::CompareFunction,
}
impl From<SamplerDescriptor> for wgpu::SamplerDescriptor {
fn from(sampler_descriptor: SamplerDescriptor) -> Self {
wgpu::SamplerDescriptor {
address_mode_u: sampler_descriptor.address_mode_u,
address_mode_v: sampler_descriptor.address_mode_v,
address_mode_w: sampler_descriptor.address_mode_w,
mag_filter: sampler_descriptor.mag_filter,
min_filter: sampler_descriptor.min_filter,
mipmap_filter: sampler_descriptor.mipmap_filter,
lod_min_clamp: sampler_descriptor.lod_min_clamp,
lod_max_clamp: sampler_descriptor.lod_max_clamp,
compare_function: sampler_descriptor.compare_function,
}
}
}
impl From<&Texture> for SamplerDescriptor {
fn from(_texture: &Texture) -> Self {
SamplerDescriptor {
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
address_mode_w: wgpu::AddressMode::ClampToEdge,
mag_filter: wgpu::FilterMode::Nearest,
min_filter: wgpu::FilterMode::Linear,
mipmap_filter: wgpu::FilterMode::Nearest,
lod_min_clamp: -100.0,
lod_max_clamp: 100.0,
compare_function: wgpu::CompareFunction::Always,
}
}
}

View file

@ -1,5 +1,10 @@
use super::{DrawTarget, PassDescriptor, PipelineDescriptor, ResourceProvider, TextureDescriptor};
use crate::asset::{AssetStorage, Handle};
use crate::{
asset::Handle,
render::{
draw_target::DrawTarget, pass::PassDescriptor, pipeline::PipelineDescriptor,
render_resource::ResourceProvider, texture::TextureDescriptor,
},
};
use std::collections::{HashMap, HashSet};
pub struct RenderGraph {
@ -37,83 +42,3 @@ impl RenderGraph {
pass_pipelines.push(pipeline);
}
}
pub struct RenderGraphBuilder {
render_graph: RenderGraph,
current_pass: Option<String>,
}
impl RenderGraphBuilder {
pub fn new() -> Self {
RenderGraphBuilder {
render_graph: RenderGraph::default(),
current_pass: None,
}
}
pub fn add_pass(mut self, name: &str, pass: PassDescriptor) -> Self {
self.current_pass = Some(name.to_string());
self.render_graph
.pass_descriptors
.insert(name.to_string(), pass);
self
}
pub fn add_pipeline(
mut self,
pipeline_descriptor_storage: &mut AssetStorage<PipelineDescriptor>,
pipeline: PipelineDescriptor,
) -> Self {
if let Some(ref pass) = self.current_pass {
let pipeline_descriptor_handle = pipeline_descriptor_storage.add(pipeline);
self.render_graph
.add_pipeline(&pass, pipeline_descriptor_handle);
}
self
}
pub fn add_pipeline_to_pass(
mut self,
pass: &str,
pipeline_descriptor_storage: &mut AssetStorage<PipelineDescriptor>,
pipeline: PipelineDescriptor,
) -> Self {
let pipeline_descriptor_handle = pipeline_descriptor_storage.add(pipeline);
self.render_graph
.add_pipeline(pass, pipeline_descriptor_handle);
self
}
pub fn add_resource_provider<T>(mut self, resource_provider: T) -> Self
where
T: ResourceProvider + 'static,
{
self.render_graph
.resource_providers
.push(Box::new(resource_provider));
self
}
pub fn add_texture(mut self, name: &str, texture_descriptor: TextureDescriptor) -> Self {
self.render_graph
.queued_textures
.push((name.to_string(), texture_descriptor));
self
}
pub fn add_draw_target<T>(mut self, draw_target: T) -> Self
where
T: DrawTarget + 'static,
{
self.render_graph
.draw_targets
.insert(draw_target.get_name(), Box::new(draw_target));
self
}
pub fn build(self) -> RenderGraph {
self.render_graph
}
}

View file

@ -0,0 +1,88 @@
use super::RenderGraph;
use crate::{
asset::AssetStorage,
render::{
draw_target::DrawTarget, pass::PassDescriptor, pipeline::PipelineDescriptor,
render_resource::ResourceProvider, texture::TextureDescriptor,
},
};
pub struct RenderGraphBuilder {
render_graph: RenderGraph,
current_pass: Option<String>,
}
impl RenderGraphBuilder {
pub fn new() -> Self {
RenderGraphBuilder {
render_graph: RenderGraph::default(),
current_pass: None,
}
}
pub fn add_pass(mut self, name: &str, pass: PassDescriptor) -> Self {
self.current_pass = Some(name.to_string());
self.render_graph
.pass_descriptors
.insert(name.to_string(), pass);
self
}
pub fn add_pipeline(
mut self,
pipeline_descriptor_storage: &mut AssetStorage<PipelineDescriptor>,
pipeline: PipelineDescriptor,
) -> Self {
if let Some(ref pass) = self.current_pass {
let pipeline_descriptor_handle = pipeline_descriptor_storage.add(pipeline);
self.render_graph
.add_pipeline(&pass, pipeline_descriptor_handle);
}
self
}
pub fn add_pipeline_to_pass(
mut self,
pass: &str,
pipeline_descriptor_storage: &mut AssetStorage<PipelineDescriptor>,
pipeline: PipelineDescriptor,
) -> Self {
let pipeline_descriptor_handle = pipeline_descriptor_storage.add(pipeline);
self.render_graph
.add_pipeline(pass, pipeline_descriptor_handle);
self
}
pub fn add_resource_provider<T>(mut self, resource_provider: T) -> Self
where
T: ResourceProvider + 'static,
{
self.render_graph
.resource_providers
.push(Box::new(resource_provider));
self
}
pub fn add_texture(mut self, name: &str, texture_descriptor: TextureDescriptor) -> Self {
self.render_graph
.queued_textures
.push((name.to_string(), texture_descriptor));
self
}
pub fn add_draw_target<T>(mut self, draw_target: T) -> Self
where
T: DrawTarget + 'static,
{
self.render_graph
.draw_targets
.insert(draw_target.get_name(), Box::new(draw_target));
self
}
pub fn build(self) -> RenderGraph {
self.render_graph
}
}

View file

@ -0,0 +1,9 @@
mod render_resource;
mod resource_info;
pub mod resource_name;
mod resource_provider;
pub mod resource_providers;
pub use render_resource::*;
pub use resource_info::*;
pub use resource_provider::*;

View file

@ -1,4 +1,4 @@
use crate::render::render_graph::Renderer;
use crate::render::renderer::Renderer;
use legion::prelude::*;
pub trait ResourceProvider {

View file

@ -1,5 +1,6 @@
use crate::render::{
render_graph::{resource_name, RenderResource, Renderer, ResourceProvider},
render_resource::{resource_name, RenderResource, ResourceProvider},
renderer::Renderer,
ActiveCamera2d, Camera,
};
use legion::prelude::*;

View file

@ -1,5 +1,6 @@
use crate::render::{
render_graph::{resource_name, RenderResource, Renderer, ResourceProvider},
render_resource::{resource_name, RenderResource, ResourceProvider},
renderer::Renderer,
ActiveCamera, Camera,
};
use bevy_transform::prelude::LocalToWorld;

View file

@ -1,6 +1,6 @@
use crate::{
prelude::World,
render::render_graph::{Renderer, ResourceProvider, TextureDescriptor},
render::{render_resource::ResourceProvider, renderer::Renderer, texture::TextureDescriptor},
};
use legion::prelude::Resources;

View file

@ -1,5 +1,6 @@
use crate::render::{
render_graph::{resource_name, RenderResource, Renderer, ResourceProvider},
render_resource::{resource_name, RenderResource, ResourceProvider},
renderer::Renderer,
Light, LightRaw,
};
use bevy_transform::prelude::{LocalToWorld, Translation};

View file

@ -1,7 +1,7 @@
use crate::{
asset::{AssetStorage, Handle, Mesh},
prelude::Renderable,
render::render_graph::{Renderer, ResourceProvider},
render::{render_resource::ResourceProvider, renderer::Renderer},
};
use legion::{filter::*, prelude::*};
use zerocopy::AsBytes;

View file

@ -2,7 +2,10 @@ use crate::{
asset::{Asset, AssetStorage, Handle, Mesh, MeshType},
ecs, math,
prelude::Node,
render::render_graph::{resource_name, RenderResource, Renderer, ResourceProvider},
render::{
render_resource::{resource_name, RenderResource, ResourceProvider},
renderer::Renderer,
},
};
use bevy_transform::prelude::Parent;
use legion::prelude::*;

View file

@ -1,9 +1,12 @@
use crate::{
asset::{AssetStorage, Texture},
render::render_graph::{
render_resource::RenderResource, AsUniforms, BindType, DynamicUniformBufferInfo,
Renderable, Renderer, ResourceProvider, SamplerDescriptor, TextureDescriptor,
UniformInfoIter,
render::{
pipeline::BindType,
render_resource::{RenderResource, ResourceProvider},
renderer::Renderer,
shader::{AsUniforms, DynamicUniformBufferInfo, UniformInfoIter},
texture::{SamplerDescriptor, TextureDescriptor},
Renderable,
},
};
use legion::prelude::*;

View file

@ -1,10 +1,10 @@
use super::PipelineDescriptor;
use super::{
pipeline::PipelineDescriptor,
shader::{Shader, ShaderSource},
};
use crate::{
asset::{AssetStorage, Handle},
render::{
render_graph::{resource_name, RenderGraph},
Shader, ShaderSource,
},
render::{render_graph::RenderGraph, render_resource::resource_name},
};
use legion::prelude::*;
use std::collections::{HashMap, HashSet};

View file

@ -0,0 +1,4 @@
mod renderer;
pub mod renderers;
pub use renderer::*;

View file

@ -1,9 +1,11 @@
use crate::{
legion::prelude::*,
render::render_graph::{
render_resource::{RenderResource, RenderResources},
DynamicUniformBufferInfo, PipelineDescriptor, RenderGraph, ResourceInfo, SamplerDescriptor,
TextureDescriptor,
render::{
pipeline::PipelineDescriptor,
render_graph::RenderGraph,
render_resource::{RenderResource, RenderResources, ResourceInfo},
shader::DynamicUniformBufferInfo,
texture::{SamplerDescriptor, TextureDescriptor},
},
};
use std::ops::Range;

View file

@ -1,6 +1,8 @@
use super::{WgpuRenderer, WgpuResources};
use crate::render::render_graph::{
BindType, PipelineDescriptor, RenderPass, RenderResource, Renderer,
use crate::render::{
pipeline::{BindType, PipelineDescriptor},
render_resource::RenderResource,
renderer::{RenderPass, Renderer},
};
use legion::prelude::Entity;

View file

@ -1,16 +1,19 @@
use super::WgpuRenderPass;
use super::{WgpuRenderPass, WgpuResources};
use crate::{
asset::{AssetStorage, Handle},
legion::prelude::*,
render::{
render_graph::{
renderers::wgpu_renderer::WgpuResources, resource_name, update_shader_assignments,
BindType, DynamicUniformBufferInfo, PassDescriptor, PipelineDescriptor, PipelineLayout,
PipelineLayoutType, RenderGraph, RenderPassColorAttachmentDescriptor,
RenderPassDepthStencilAttachmentDescriptor, RenderResource, RenderResources, Renderer,
ResourceInfo, SamplerDescriptor, TextureDescriptor,
pass::{
PassDescriptor, RenderPassColorAttachmentDescriptor,
RenderPassDepthStencilAttachmentDescriptor,
},
Shader,
pipeline::{BindType, PipelineDescriptor, PipelineLayout, PipelineLayoutType},
render_graph::RenderGraph,
render_resource::{resource_name, RenderResource, RenderResources, ResourceInfo},
renderer::Renderer,
shader::{DynamicUniformBufferInfo, Shader},
texture::{SamplerDescriptor, TextureDescriptor},
update_shader_assignments,
},
};
use std::{collections::HashMap, ops::Deref};

View file

@ -1,8 +1,10 @@
use crate::{
legion::prelude::*,
render::render_graph::{
BindGroup, BindType, DynamicUniformBufferInfo, RenderResource, RenderResources,
ResourceInfo, SamplerDescriptor, TextureDescriptor,
render::{
pipeline::{BindGroup, BindType},
render_resource::{RenderResource, RenderResources, ResourceInfo},
shader::DynamicUniformBufferInfo,
texture::{SamplerDescriptor, TextureDescriptor},
},
};
use std::{borrow::Cow, collections::HashMap};

8
src/render/shader/mod.rs Normal file
View file

@ -0,0 +1,8 @@
mod shader;
mod shader_reflect;
mod uniform;
pub mod uniforms;
pub use shader::*;
pub use shader_reflect::*;
pub use uniform::*;

View file

@ -1,7 +1,5 @@
use crate::{
asset::Handle,
render::shader_reflect::{get_shader_layout, ShaderLayout},
};
use super::ShaderLayout;
use crate::asset::Handle;
use std::marker::Copy;
#[derive(Hash, Eq, PartialEq, Copy, Clone, Debug)]
@ -84,7 +82,7 @@ impl Shader {
pub fn reflect_layout(&self) -> Option<ShaderLayout> {
if let ShaderSource::Spirv(ref spirv) = self.source {
Some(get_shader_layout(spirv.as_slice()))
Some(ShaderLayout::from_spirv(spirv.as_slice()))
} else {
panic!("Cannot reflect layout of non-SpirV shader. Try compiling this shader to SpirV first using self.get_spirv_shader()");
}

View file

@ -1,5 +1,6 @@
use crate::render::render_graph::{
BindGroup, BindType, Binding, TextureViewDimension, UniformProperty, UniformPropertyType,
use crate::render::{
pipeline::{BindGroup, BindType, Binding, UniformProperty, UniformPropertyType},
texture::TextureViewDimension,
};
use spirv_reflect::{
types::{
@ -29,22 +30,24 @@ pub struct ShaderLayout {
pub entry_point: String,
}
pub fn get_shader_layout(spirv_data: &[u32]) -> ShaderLayout {
match ShaderModule::load_u8_data(spirv_data.as_bytes()) {
Ok(ref mut module) => {
let entry_point_name = module.get_entry_point_name();
let mut bind_groups = Vec::new();
for descriptor_set in module.enumerate_descriptor_sets(None).unwrap() {
let bind_group = reflect_bind_group(&descriptor_set);
bind_groups.push(bind_group);
}
impl ShaderLayout {
pub fn from_spirv(spirv_data: &[u32]) -> ShaderLayout {
match ShaderModule::load_u8_data(spirv_data.as_bytes()) {
Ok(ref mut module) => {
let entry_point_name = module.get_entry_point_name();
let mut bind_groups = Vec::new();
for descriptor_set in module.enumerate_descriptor_sets(None).unwrap() {
let bind_group = reflect_bind_group(&descriptor_set);
bind_groups.push(bind_group);
}
ShaderLayout {
bind_groups,
entry_point: entry_point_name,
ShaderLayout {
bind_groups,
entry_point: entry_point_name,
}
}
Err(err) => panic!("Failed to reflect shader layout: {:?}", err),
}
Err(err) => panic!("Failed to reflect shader layout: {:?}", err),
}
}
@ -180,10 +183,7 @@ fn reflect_uniform_numeric(type_description: &ReflectTypeDescription) -> Uniform
#[cfg(test)]
mod tests {
use super::*;
use crate::render::{
render_graph::{BindGroup, BindType, Binding, UniformProperty, UniformPropertyType},
Shader, ShaderStage,
};
use crate::render::shader::{Shader, ShaderStage};
#[test]
fn test_reflection() {

View file

@ -1,10 +1,7 @@
use crate::{
asset::{Handle, Texture},
core::GetBytes,
render::{
color::ColorSource,
render_graph::{BindType, TextureViewDimension},
},
render::{color::ColorSource, pipeline::BindType, texture::TextureViewDimension},
};
use legion::prelude::Entity;
use std::collections::HashMap;

View file

@ -1,6 +1,6 @@
use crate::{
asset::{Handle, Texture},
render::render_graph::{uniform::AsUniforms, FieldBindType, FieldUniformName},
render::shader::{AsUniforms, FieldBindType, FieldUniformName},
};
use zerocopy::AsBytes;

View file

@ -0,0 +1,7 @@
mod sampler_descriptor;
mod texture_descriptor;
mod texture_dimension;
pub use sampler_descriptor::*;
pub use texture_descriptor::*;
pub use texture_dimension::*;

View file

@ -0,0 +1,46 @@
use crate::asset::Texture;
#[derive(Copy, Clone)]
pub struct SamplerDescriptor {
pub address_mode_u: wgpu::AddressMode,
pub address_mode_v: wgpu::AddressMode,
pub address_mode_w: wgpu::AddressMode,
pub mag_filter: wgpu::FilterMode,
pub min_filter: wgpu::FilterMode,
pub mipmap_filter: wgpu::FilterMode,
pub lod_min_clamp: f32,
pub lod_max_clamp: f32,
pub compare_function: wgpu::CompareFunction,
}
impl From<SamplerDescriptor> for wgpu::SamplerDescriptor {
fn from(sampler_descriptor: SamplerDescriptor) -> Self {
wgpu::SamplerDescriptor {
address_mode_u: sampler_descriptor.address_mode_u,
address_mode_v: sampler_descriptor.address_mode_v,
address_mode_w: sampler_descriptor.address_mode_w,
mag_filter: sampler_descriptor.mag_filter,
min_filter: sampler_descriptor.min_filter,
mipmap_filter: sampler_descriptor.mipmap_filter,
lod_min_clamp: sampler_descriptor.lod_min_clamp,
lod_max_clamp: sampler_descriptor.lod_max_clamp,
compare_function: sampler_descriptor.compare_function,
}
}
}
impl From<&Texture> for SamplerDescriptor {
fn from(_texture: &Texture) -> Self {
SamplerDescriptor {
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
address_mode_w: wgpu::AddressMode::ClampToEdge,
mag_filter: wgpu::FilterMode::Nearest,
min_filter: wgpu::FilterMode::Linear,
mipmap_filter: wgpu::FilterMode::Nearest,
lod_min_clamp: -100.0,
lod_max_clamp: 100.0,
compare_function: wgpu::CompareFunction::Always,
}
}
}

View file

@ -0,0 +1,45 @@
use super::TextureDimension;
use crate::asset::Texture;
#[derive(Copy, Clone)]
pub struct TextureDescriptor {
pub size: wgpu::Extent3d,
pub array_layer_count: u32,
pub mip_level_count: u32,
pub sample_count: u32,
pub dimension: TextureDimension,
pub format: wgpu::TextureFormat,
pub usage: wgpu::TextureUsage,
}
impl From<&Texture> for TextureDescriptor {
fn from(texture: &Texture) -> Self {
TextureDescriptor {
size: wgpu::Extent3d {
height: texture.height as u32,
width: texture.width as u32,
depth: 1,
},
array_layer_count: 1,
mip_level_count: 1,
sample_count: 1,
dimension: TextureDimension::D2,
format: wgpu::TextureFormat::Rgba8UnormSrgb,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
}
}
}
impl From<TextureDescriptor> for wgpu::TextureDescriptor {
fn from(texture_descriptor: TextureDescriptor) -> Self {
wgpu::TextureDescriptor {
size: texture_descriptor.size,
array_layer_count: texture_descriptor.array_layer_count,
mip_level_count: texture_descriptor.mip_level_count,
sample_count: texture_descriptor.sample_count,
dimension: texture_descriptor.dimension.into(),
format: texture_descriptor.format,
usage: texture_descriptor.usage,
}
}
}

View file

@ -0,0 +1,39 @@
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub enum TextureViewDimension {
D1,
D2,
D2Array,
Cube,
CubeArray,
D3,
}
impl From<TextureViewDimension> for wgpu::TextureViewDimension {
fn from(dimension: TextureViewDimension) -> Self {
match dimension {
TextureViewDimension::D1 => wgpu::TextureViewDimension::D1,
TextureViewDimension::D2 => wgpu::TextureViewDimension::D2,
TextureViewDimension::D2Array => wgpu::TextureViewDimension::D2Array,
TextureViewDimension::Cube => wgpu::TextureViewDimension::Cube,
TextureViewDimension::CubeArray => wgpu::TextureViewDimension::CubeArray,
TextureViewDimension::D3 => wgpu::TextureViewDimension::D3,
}
}
}
#[derive(Copy, Clone, Debug, Hash)]
pub enum TextureDimension {
D1,
D2,
D3,
}
impl From<TextureDimension> for wgpu::TextureDimension {
fn from(dimension: TextureDimension) -> Self {
match dimension {
TextureDimension::D1 => wgpu::TextureDimension::D1,
TextureDimension::D2 => wgpu::TextureDimension::D2,
TextureDimension::D3 => wgpu::TextureDimension::D3,
}
}
}

View file

@ -1,4 +1,4 @@
use crate::render::render_graph::VertexBufferDescriptor;
use super::pipeline::VertexBufferDescriptor;
use std::convert::From;
use zerocopy::{AsBytes, FromBytes};