mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 06:00:20 +00:00
reorganize render modules
This commit is contained in:
parent
ccb240c4c4
commit
aa09e93980
71 changed files with 617 additions and 547 deletions
|
@ -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()),)*
|
||||
];
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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},
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
|||
asset::{Handle, Texture},
|
||||
core::GetBytes,
|
||||
math::Vec4,
|
||||
render::render_graph::ShaderDefSuffixProvider,
|
||||
render::shader::ShaderDefSuffixProvider,
|
||||
};
|
||||
|
||||
pub enum ColorSource {
|
||||
|
|
|
@ -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};
|
||||
|
|
@ -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();
|
|
@ -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>,
|
||||
) {
|
||||
}
|
|
@ -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
|
4
src/render/draw_target/mod.rs
Normal file
4
src/render/draw_target/mod.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
mod draw_target;
|
||||
pub mod draw_targets;
|
||||
|
||||
pub use draw_target::*;
|
|
@ -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
4
src/render/pass/mod.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
mod pass;
|
||||
pub mod passes;
|
||||
|
||||
pub use pass::*;
|
|
@ -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 {
|
55
src/render/pipeline/bind_group.rs
Normal file
55
src/render/pipeline/bind_group.rs
Normal 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 {}
|
43
src/render/pipeline/binding.rs
Normal file
43
src/render/pipeline/binding.rs
Normal 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,
|
||||
}
|
||||
}
|
||||
}
|
10
src/render/pipeline/mod.rs
Normal file
10
src/render/pipeline/mod.rs
Normal 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::*;
|
|
@ -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,
|
||||
},
|
93
src/render/pipeline/pipeline_layout.rs
Normal file
93
src/render/pipeline/pipeline_layout.rs
Normal 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,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
},
|
|
@ -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,
|
||||
},
|
|
@ -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,
|
||||
},
|
|
@ -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::*;
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
88
src/render/render_graph/render_graph_builder.rs
Normal file
88
src/render/render_graph/render_graph_builder.rs
Normal 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
|
||||
}
|
||||
}
|
9
src/render/render_resource/mod.rs
Normal file
9
src/render/render_resource/mod.rs
Normal 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::*;
|
|
@ -1,4 +1,4 @@
|
|||
use crate::render::render_graph::Renderer;
|
||||
use crate::render::renderer::Renderer;
|
||||
use legion::prelude::*;
|
||||
|
||||
pub trait ResourceProvider {
|
|
@ -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::*;
|
|
@ -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;
|
|
@ -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;
|
||||
|
|
@ -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};
|
|
@ -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;
|
|
@ -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::*;
|
|
@ -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::*;
|
|
@ -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};
|
4
src/render/renderer/mod.rs
Normal file
4
src/render/renderer/mod.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
mod renderer;
|
||||
pub mod renderers;
|
||||
|
||||
pub use renderer::*;
|
|
@ -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;
|
|
@ -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;
|
||||
|
|
@ -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};
|
|
@ -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
8
src/render/shader/mod.rs
Normal 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::*;
|
|
@ -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()");
|
||||
}
|
|
@ -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() {
|
|
@ -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;
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
asset::{Handle, Texture},
|
||||
render::render_graph::{uniform::AsUniforms, FieldBindType, FieldUniformName},
|
||||
render::shader::{AsUniforms, FieldBindType, FieldUniformName},
|
||||
};
|
||||
|
||||
use zerocopy::AsBytes;
|
7
src/render/texture/mod.rs
Normal file
7
src/render/texture/mod.rs
Normal 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::*;
|
46
src/render/texture/sampler_descriptor.rs
Normal file
46
src/render/texture/sampler_descriptor.rs
Normal 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,
|
||||
}
|
||||
}
|
||||
}
|
45
src/render/texture/texture_descriptor.rs
Normal file
45
src/render/texture/texture_descriptor.rs
Normal 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,
|
||||
}
|
||||
}
|
||||
}
|
39
src/render/texture/texture_dimension.rs
Normal file
39
src/render/texture/texture_dimension.rs
Normal 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,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::render::render_graph::VertexBufferDescriptor;
|
||||
use super::pipeline::VertexBufferDescriptor;
|
||||
use std::convert::From;
|
||||
use zerocopy::{AsBytes, FromBytes};
|
||||
|
||||
|
|
Loading…
Reference in a new issue