mirror of
https://github.com/bevyengine/bevy
synced 2025-02-16 14:08:32 +00:00
Make PipelineDescriptor an Asset that references Handle<Shader>
This commit is contained in:
parent
478d475219
commit
4de039eb71
17 changed files with 275 additions and 255 deletions
|
@ -16,7 +16,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use bevy_transform::{prelude::LocalToWorld, transform_system_bundle};
|
use bevy_transform::{prelude::LocalToWorld, transform_system_bundle};
|
||||||
use render_graph_2::CompiledShaderMap;
|
use render_graph_2::{CompiledShaderMap, PipelineDescriptor};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub struct AppBuilder {
|
pub struct AppBuilder {
|
||||||
|
@ -166,6 +166,7 @@ impl AppBuilder {
|
||||||
resources.insert(AssetStorage::<Mesh>::new());
|
resources.insert(AssetStorage::<Mesh>::new());
|
||||||
resources.insert(AssetStorage::<Texture>::new());
|
resources.insert(AssetStorage::<Texture>::new());
|
||||||
resources.insert(AssetStorage::<Shader>::new());
|
resources.insert(AssetStorage::<Shader>::new());
|
||||||
|
resources.insert(AssetStorage::<PipelineDescriptor>::new());
|
||||||
resources.insert(ShaderAssignments::new());
|
resources.insert(ShaderAssignments::new());
|
||||||
resources.insert(CompiledShaderMap::new());
|
resources.insert(CompiledShaderMap::new());
|
||||||
self
|
self
|
||||||
|
@ -181,17 +182,29 @@ impl AppBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_render_graph_defaults(mut self) -> Self {
|
pub fn add_render_graph_defaults(mut self) -> Self {
|
||||||
self.render_graph_builder = self
|
{
|
||||||
.render_graph_builder
|
let mut pipeline_storage = self
|
||||||
.add_resource_provider(Box::new(CameraResourceProvider))
|
.world
|
||||||
.add_resource_provider(Box::new(Camera2dResourceProvider))
|
.resources
|
||||||
.add_resource_provider(Box::new(LightResourceProvider::new(10)))
|
.get_mut::<AssetStorage<PipelineDescriptor>>()
|
||||||
.add_resource_provider(Box::new(UiResourceProvider::new()))
|
.unwrap();
|
||||||
.add_resource_provider(Box::new(UniformResourceProvider::<StandardMaterial>::new()))
|
let mut shader_storage = self
|
||||||
.add_resource_provider(Box::new(UniformResourceProvider::<LocalToWorld>::new()))
|
.world
|
||||||
.add_forward_pass()
|
.resources
|
||||||
.add_forward_pipeline()
|
.get_mut::<AssetStorage<Shader>>()
|
||||||
.add_ui_pipeline();
|
.unwrap();
|
||||||
|
self.render_graph_builder = self
|
||||||
|
.render_graph_builder
|
||||||
|
.add_resource_provider(Box::new(CameraResourceProvider))
|
||||||
|
.add_resource_provider(Box::new(Camera2dResourceProvider))
|
||||||
|
.add_resource_provider(Box::new(LightResourceProvider::new(10)))
|
||||||
|
.add_resource_provider(Box::new(UiResourceProvider::new()))
|
||||||
|
.add_resource_provider(Box::new(UniformResourceProvider::<StandardMaterial>::new()))
|
||||||
|
.add_resource_provider(Box::new(UniformResourceProvider::<LocalToWorld>::new()))
|
||||||
|
.add_forward_pass()
|
||||||
|
.add_forward_pipeline(&mut pipeline_storage, &mut shader_storage)
|
||||||
|
.add_ui_pipeline(&mut pipeline_storage, &mut shader_storage);
|
||||||
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,17 +3,31 @@ mod mesh;
|
||||||
mod texture;
|
mod texture;
|
||||||
|
|
||||||
pub use self::gltf::load_gltf;
|
pub use self::gltf::load_gltf;
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
pub use mesh::*;
|
pub use mesh::*;
|
||||||
pub use texture::*;
|
pub use texture::*;
|
||||||
|
|
||||||
use std::{collections::HashMap, marker::PhantomData};
|
use std::{collections::HashMap, marker::PhantomData};
|
||||||
|
|
||||||
#[derive(Hash, Eq, PartialEq)]
|
|
||||||
pub struct Handle<T> {
|
pub struct Handle<T> {
|
||||||
pub id: usize,
|
pub id: usize,
|
||||||
marker: PhantomData<T>,
|
marker: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Hash for Handle<T> {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
self.id.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PartialEq for Handle<T> {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.id == other.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Eq for Handle<T> {}
|
||||||
|
|
||||||
// TODO: somehow handle this gracefully in asset managers. or alternatively remove Default
|
// TODO: somehow handle this gracefully in asset managers. or alternatively remove Default
|
||||||
impl<T> Default for Handle<T> {
|
impl<T> Default for Handle<T> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
@ -75,11 +89,19 @@ impl<T> AssetStorage<T> {
|
||||||
handle
|
handle
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_id(&mut self, id: usize) -> Option<&mut T> {
|
pub fn get_id(&self, id: usize) -> Option<&T> {
|
||||||
|
self.assets.get(&id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_id_mut(&mut self, id: usize) -> Option<&mut T> {
|
||||||
self.assets.get_mut(&id)
|
self.assets.get_mut(&id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&mut self, handle: &Handle<T>) -> Option<&mut T> {
|
pub fn get(&self, handle: &Handle<T>) -> Option<&T> {
|
||||||
|
self.assets.get(&handle.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_mut(&mut self, handle: &Handle<T>) -> Option<&mut T> {
|
||||||
self.assets.get_mut(&handle.id)
|
self.assets.get_mut(&handle.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,7 @@ impl Pipeline for ForwardPipeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
if should_load_mesh {
|
if should_load_mesh {
|
||||||
if let Some(mesh_asset) = mesh_storage.get_id(mesh.id) {
|
if let Some(mesh_asset) = mesh_storage.get_id_mut(mesh.id) {
|
||||||
mesh_asset.setup_buffers(&render_graph.device);
|
mesh_asset.setup_buffers(&render_graph.device);
|
||||||
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);
|
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);
|
||||||
pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]);
|
pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]);
|
||||||
|
|
|
@ -285,7 +285,7 @@ impl Pipeline for ForwardInstancedPipeline {
|
||||||
|
|
||||||
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||||
for instance_buffer_info in self.instance_buffer_infos.as_ref().unwrap().iter() {
|
for instance_buffer_info in self.instance_buffer_infos.as_ref().unwrap().iter() {
|
||||||
if let Some(mesh_asset) = mesh_storage.get_id(instance_buffer_info.mesh_id) {
|
if let Some(mesh_asset) = mesh_storage.get_id_mut(instance_buffer_info.mesh_id) {
|
||||||
mesh_asset.setup_buffers(&render_graph.device);
|
mesh_asset.setup_buffers(&render_graph.device);
|
||||||
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);
|
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);
|
||||||
pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]);
|
pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]);
|
||||||
|
|
|
@ -176,7 +176,7 @@ impl Pipeline for ForwardShadowPassNew {
|
||||||
|
|
||||||
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||||
for (material, mesh) in mesh_query.iter(world) {
|
for (material, mesh) in mesh_query.iter(world) {
|
||||||
if let Some(mesh_asset) = mesh_storage.get_id(mesh.id) {
|
if let Some(mesh_asset) = mesh_storage.get_id_mut(mesh.id) {
|
||||||
mesh_asset.setup_buffers(&render_graph.device);
|
mesh_asset.setup_buffers(&render_graph.device);
|
||||||
pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]);
|
pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]);
|
||||||
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);
|
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);
|
||||||
|
|
|
@ -166,7 +166,7 @@ impl Pipeline for ShadowPipeline {
|
||||||
|
|
||||||
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||||
for (material, mesh) in mesh_query.iter(world) {
|
for (material, mesh) in mesh_query.iter(world) {
|
||||||
if let Some(mesh_asset) = mesh_storage.get_id(mesh.id) {
|
if let Some(mesh_asset) = mesh_storage.get_id_mut(mesh.id) {
|
||||||
mesh_asset.setup_buffers(&render_graph.device);
|
mesh_asset.setup_buffers(&render_graph.device);
|
||||||
|
|
||||||
pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]);
|
pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]);
|
||||||
|
|
|
@ -242,7 +242,7 @@ impl Pipeline for UiPipeline {
|
||||||
|
|
||||||
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||||
for instance_buffer_info in instance_buffer_infos.as_ref().unwrap().iter() {
|
for instance_buffer_info in instance_buffer_infos.as_ref().unwrap().iter() {
|
||||||
if let Some(mesh_asset) = mesh_storage.get_id(instance_buffer_info.mesh_id) {
|
if let Some(mesh_asset) = mesh_storage.get_id_mut(instance_buffer_info.mesh_id) {
|
||||||
mesh_asset.setup_buffers(&render_graph.device);
|
mesh_asset.setup_buffers(&render_graph.device);
|
||||||
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);
|
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);
|
||||||
pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]);
|
pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]);
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::{
|
||||||
use zerocopy::AsBytes;
|
use zerocopy::AsBytes;
|
||||||
|
|
||||||
pub fn mesh_draw_target(world: &World, render_pass: &mut dyn RenderPass) {
|
pub fn mesh_draw_target(world: &World, render_pass: &mut dyn RenderPass) {
|
||||||
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
let mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||||
let mut current_mesh_id = None;
|
let mut current_mesh_id = None;
|
||||||
let mut current_mesh_index_length = 0;
|
let mut current_mesh_index_length = 0;
|
||||||
let mesh_query = <(Read<ShaderUniforms>, Read<Handle<Mesh>>, Read<Renderable>)>::query()
|
let mesh_query = <(Read<ShaderUniforms>, Read<Handle<Mesh>>, Read<Renderable>)>::query()
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
use zerocopy::AsBytes;
|
use zerocopy::AsBytes;
|
||||||
|
|
||||||
pub fn ui_draw_target(world: &World, render_pass: &mut dyn RenderPass) {
|
pub fn ui_draw_target(world: &World, render_pass: &mut dyn RenderPass) {
|
||||||
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
let mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||||
// NOTE: this is ugly and borrowing is stupid
|
// NOTE: this is ugly and borrowing is stupid
|
||||||
let result = {
|
let result = {
|
||||||
let renderer = render_pass.get_renderer();
|
let renderer = render_pass.get_renderer();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::render::{
|
use crate::{asset::{AssetStorage, Handle}, render::{
|
||||||
render_graph_2::{BindGroup, DrawTarget, PipelineLayout},
|
render_graph_2::{BindGroup, DrawTarget, PipelineLayout},
|
||||||
shader::{Shader, ShaderStages},
|
shader::{Shader, ShaderStages},
|
||||||
};
|
}};
|
||||||
|
|
||||||
pub struct VertexBufferDescriptor {
|
pub struct VertexBufferDescriptor {
|
||||||
pub stride: wgpu::BufferAddress,
|
pub stride: wgpu::BufferAddress,
|
||||||
|
@ -55,7 +55,7 @@ pub struct PipelineDescriptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PipelineDescriptor {
|
impl PipelineDescriptor {
|
||||||
fn new(vertex_shader: Shader) -> Self {
|
fn new(vertex_shader: Handle<Shader>) -> Self {
|
||||||
PipelineDescriptor {
|
PipelineDescriptor {
|
||||||
pipeline_layout: PipelineLayout::new(),
|
pipeline_layout: PipelineLayout::new(),
|
||||||
color_states: Vec::new(),
|
color_states: Vec::new(),
|
||||||
|
@ -80,19 +80,22 @@ impl PipelineDescriptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PipelineDescriptor {
|
impl PipelineDescriptor {
|
||||||
pub fn build(vertex_shader: Shader) -> PipelineBuilder {
|
pub fn build(shader_storage: &mut AssetStorage<Shader>, vertex_shader: Shader) -> PipelineBuilder {
|
||||||
PipelineBuilder::new(vertex_shader)
|
PipelineBuilder::new(shader_storage, vertex_shader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PipelineBuilder {
|
pub struct PipelineBuilder<'a> {
|
||||||
pipeline: PipelineDescriptor,
|
pipeline: PipelineDescriptor,
|
||||||
|
shader_storage: &'a mut AssetStorage<Shader>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PipelineBuilder {
|
impl<'a> PipelineBuilder<'a> {
|
||||||
pub fn new(vertex_shader: Shader) -> Self {
|
pub fn new(shader_storage: &'a mut AssetStorage<Shader>, vertex_shader: Shader) -> Self {
|
||||||
|
let vertex_shader_handle = shader_storage.add(vertex_shader);
|
||||||
PipelineBuilder {
|
PipelineBuilder {
|
||||||
pipeline: PipelineDescriptor::new(vertex_shader),
|
pipeline: PipelineDescriptor::new(vertex_shader_handle),
|
||||||
|
shader_storage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +104,8 @@ impl PipelineBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_fragment_shader(mut self, fragment_shader: Shader) -> Self {
|
pub fn with_fragment_shader(mut self, fragment_shader: Shader) -> Self {
|
||||||
self.pipeline.shader_stages.fragment = Some(fragment_shader);
|
let fragment_shader_handle = self.shader_storage.add(fragment_shader);
|
||||||
|
self.pipeline.shader_stages.fragment = Some(fragment_shader_handle);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
use crate::render::{
|
use crate::{asset::AssetStorage, render::{
|
||||||
render_graph_2::{
|
render_graph_2::{
|
||||||
draw_targets::mesh_draw_target, pipeline_layout::*, PipelineDescriptor, RenderGraphBuilder,
|
draw_targets::mesh_draw_target, pipeline_layout::*, PipelineDescriptor, RenderGraphBuilder,
|
||||||
},
|
},
|
||||||
shader::{Shader, ShaderStage},
|
shader::{Shader, ShaderStage},
|
||||||
Vertex,
|
Vertex,
|
||||||
};
|
}};
|
||||||
pub trait ForwardPipelineBuilder {
|
pub trait ForwardPipelineBuilder {
|
||||||
fn add_forward_pipeline(self) -> Self;
|
fn add_forward_pipeline(self, pipeline_descriptor_storage: &mut AssetStorage<PipelineDescriptor>, shader_storage: &mut AssetStorage<Shader>) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ForwardPipelineBuilder for RenderGraphBuilder {
|
impl ForwardPipelineBuilder for RenderGraphBuilder {
|
||||||
fn add_forward_pipeline(self) -> Self {
|
fn add_forward_pipeline(self, pipeline_descriptor_storage: &mut AssetStorage<PipelineDescriptor>, shader_storage: &mut AssetStorage<Shader>) -> Self {
|
||||||
self.add_pipeline(
|
self.add_pipeline(
|
||||||
"forward",
|
pipeline_descriptor_storage,
|
||||||
PipelineDescriptor::build(Shader::from_glsl(
|
PipelineDescriptor::build(
|
||||||
include_str!("forward.vert"),
|
shader_storage,
|
||||||
ShaderStage::Vertex,
|
Shader::from_glsl(include_str!("forward.vert"), ShaderStage::Vertex),
|
||||||
))
|
)
|
||||||
.with_fragment_shader(Shader::from_glsl(
|
.with_fragment_shader(Shader::from_glsl(
|
||||||
include_str!("forward.frag"),
|
include_str!("forward.frag"),
|
||||||
ShaderStage::Fragment,
|
ShaderStage::Fragment,
|
||||||
|
|
|
@ -1,22 +1,35 @@
|
||||||
use crate::render::{
|
use crate::{
|
||||||
render_graph_2::{
|
asset::AssetStorage,
|
||||||
draw_targets::mesh_draw_target, pipeline_layout::*, PipelineDescriptor, RenderGraphBuilder,
|
render::{
|
||||||
|
render_graph_2::{
|
||||||
|
draw_targets::mesh_draw_target, pipeline_layout::*, PipelineDescriptor,
|
||||||
|
RenderGraphBuilder,
|
||||||
|
},
|
||||||
|
shader::{Shader, ShaderStage},
|
||||||
|
Vertex,
|
||||||
},
|
},
|
||||||
shader::{Shader, ShaderStage},
|
|
||||||
Vertex,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait ForwardFlatPipelineBuilder {
|
pub trait ForwardFlatPipelineBuilder {
|
||||||
fn add_forward_flat_pipeline(self) -> Self;
|
fn add_forward_flat_pipeline(
|
||||||
|
self,
|
||||||
|
pipeline_descriptor_storage: &mut AssetStorage<PipelineDescriptor>,
|
||||||
|
shader_storage: &mut AssetStorage<Shader>,
|
||||||
|
) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ForwardFlatPipelineBuilder for RenderGraphBuilder {
|
impl ForwardFlatPipelineBuilder for RenderGraphBuilder {
|
||||||
fn add_forward_flat_pipeline(self) -> Self {
|
fn add_forward_flat_pipeline(
|
||||||
|
self,
|
||||||
|
pipeline_descriptor_storage: &mut AssetStorage<PipelineDescriptor>,
|
||||||
|
shader_storage: &mut AssetStorage<Shader>,
|
||||||
|
) -> Self {
|
||||||
self.add_pipeline(
|
self.add_pipeline(
|
||||||
"forward_flat",
|
pipeline_descriptor_storage,
|
||||||
PipelineDescriptor::build(Shader::from_glsl(
|
PipelineDescriptor::build(
|
||||||
include_str!("forward_flat.vert"),
|
shader_storage,
|
||||||
ShaderStage::Vertex,
|
Shader::from_glsl(include_str!("forward_flat.vert"), ShaderStage::Vertex),
|
||||||
))
|
)
|
||||||
.with_fragment_shader(Shader::from_glsl(
|
.with_fragment_shader(Shader::from_glsl(
|
||||||
include_str!("forward_flat.frag"),
|
include_str!("forward_flat.frag"),
|
||||||
ShaderStage::Fragment,
|
ShaderStage::Fragment,
|
||||||
|
|
|
@ -1,23 +1,34 @@
|
||||||
use crate::render::{
|
use crate::{
|
||||||
render_graph_2::{
|
asset::AssetStorage,
|
||||||
draw_targets::ui_draw_target, pipeline_layout::*, resource_providers::RectData,
|
render::{
|
||||||
PipelineDescriptor, RenderGraphBuilder, VertexBufferDescriptor,
|
render_graph_2::{
|
||||||
|
draw_targets::ui_draw_target, pipeline_layout::*, resource_providers::RectData,
|
||||||
|
PipelineDescriptor, RenderGraphBuilder, VertexBufferDescriptor,
|
||||||
|
},
|
||||||
|
shader::{Shader, ShaderStage},
|
||||||
|
Vertex,
|
||||||
},
|
},
|
||||||
shader::{Shader, ShaderStage},
|
|
||||||
Vertex,
|
|
||||||
};
|
};
|
||||||
pub trait UiPipelineBuilder {
|
pub trait UiPipelineBuilder {
|
||||||
fn add_ui_pipeline(self) -> Self;
|
fn add_ui_pipeline(
|
||||||
|
self,
|
||||||
|
pipeline_descriptor_storage: &mut AssetStorage<PipelineDescriptor>,
|
||||||
|
shader_storage: &mut AssetStorage<Shader>,
|
||||||
|
) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UiPipelineBuilder for RenderGraphBuilder {
|
impl UiPipelineBuilder for RenderGraphBuilder {
|
||||||
fn add_ui_pipeline(self) -> Self {
|
fn add_ui_pipeline(
|
||||||
|
self,
|
||||||
|
pipeline_descriptor_storage: &mut AssetStorage<PipelineDescriptor>,
|
||||||
|
shader_storage: &mut AssetStorage<Shader>,
|
||||||
|
) -> Self {
|
||||||
self.add_pipeline(
|
self.add_pipeline(
|
||||||
"ui",
|
pipeline_descriptor_storage,
|
||||||
PipelineDescriptor::build(Shader::from_glsl(
|
PipelineDescriptor::build(
|
||||||
include_str!("ui.vert"),
|
shader_storage,
|
||||||
ShaderStage::Vertex,
|
Shader::from_glsl(include_str!("ui.vert"), ShaderStage::Vertex),
|
||||||
))
|
)
|
||||||
.with_fragment_shader(Shader::from_glsl(
|
.with_fragment_shader(Shader::from_glsl(
|
||||||
include_str!("ui.frag"),
|
include_str!("ui.frag"),
|
||||||
ShaderStage::Fragment,
|
ShaderStage::Fragment,
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
use crate::render::render_graph_2::{
|
use crate::{
|
||||||
PassDescriptor, PipelineDescriptor, ResourceProvider, TextureDescriptor,
|
asset::{AssetStorage, Handle},
|
||||||
|
render::{
|
||||||
|
render_graph_2::{PassDescriptor, PipelineDescriptor, ResourceProvider, TextureDescriptor},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
pub struct RenderGraph {
|
pub struct RenderGraph {
|
||||||
pub pipeline_descriptors: HashMap<String, PipelineDescriptor>,
|
pub pipeline_descriptors: HashSet<Handle<PipelineDescriptor>>,
|
||||||
// TODO: make this ordered
|
// TODO: make this ordered
|
||||||
pub pass_descriptors: HashMap<String, PassDescriptor>,
|
pub pass_descriptors: HashMap<String, PassDescriptor>,
|
||||||
pub pass_pipelines: HashMap<String, Vec<String>>,
|
pub pass_pipelines: HashMap<String, Vec<Handle<PipelineDescriptor>>>,
|
||||||
pub resource_providers: Vec<Box<dyn ResourceProvider>>,
|
pub resource_providers: Vec<Box<dyn ResourceProvider>>,
|
||||||
pub queued_textures: Vec<(String, TextureDescriptor)>,
|
pub queued_textures: Vec<(String, TextureDescriptor)>,
|
||||||
}
|
}
|
||||||
|
@ -15,7 +18,7 @@ pub struct RenderGraph {
|
||||||
impl Default for RenderGraph {
|
impl Default for RenderGraph {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
RenderGraph {
|
RenderGraph {
|
||||||
pipeline_descriptors: HashMap::new(),
|
pipeline_descriptors: HashSet::new(),
|
||||||
pass_descriptors: HashMap::new(),
|
pass_descriptors: HashMap::new(),
|
||||||
pass_pipelines: HashMap::new(),
|
pass_pipelines: HashMap::new(),
|
||||||
resource_providers: Vec::new(),
|
resource_providers: Vec::new(),
|
||||||
|
@ -24,9 +27,23 @@ impl Default for RenderGraph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RenderGraph {
|
||||||
|
pub fn add_pipeline(&mut self, pass: &str, pipeline: Handle<PipelineDescriptor>) {
|
||||||
|
self.pipeline_descriptors.insert(pipeline.clone());
|
||||||
|
|
||||||
|
if let None = self.pass_pipelines.get(pass) {
|
||||||
|
self.pass_pipelines.insert(pass.to_string(), Vec::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
let pass_pipelines = self.pass_pipelines.get_mut(pass).unwrap();
|
||||||
|
pass_pipelines.push(pipeline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct RenderGraphBuilder {
|
pub struct RenderGraphBuilder {
|
||||||
render_graph: RenderGraph,
|
render_graph: RenderGraph,
|
||||||
current_pass: Option<String>,
|
current_pass: Option<String>,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderGraphBuilder {
|
impl RenderGraphBuilder {
|
||||||
|
@ -45,24 +62,10 @@ impl RenderGraphBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_pipeline(mut self, name: &str, pipeline: PipelineDescriptor) -> Self {
|
pub fn add_pipeline(mut self, pipeline_descriptor_storage: &mut AssetStorage<PipelineDescriptor>, pipeline: PipelineDescriptor) -> Self {
|
||||||
self.render_graph
|
if let Some(ref pass) = self.current_pass {
|
||||||
.pipeline_descriptors
|
let pipeline_descriptor_handle = pipeline_descriptor_storage.add(pipeline);
|
||||||
.insert(name.to_string(), pipeline);
|
self.render_graph.add_pipeline(&pass, pipeline_descriptor_handle);
|
||||||
|
|
||||||
if let Some(current_pass) = self.current_pass.as_ref() {
|
|
||||||
if let None = self.render_graph.pass_pipelines.get(current_pass) {
|
|
||||||
self.render_graph
|
|
||||||
.pass_pipelines
|
|
||||||
.insert(current_pass.to_string(), Vec::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
let pass_pipelines = self
|
|
||||||
.render_graph
|
|
||||||
.pass_pipelines
|
|
||||||
.get_mut(current_pass)
|
|
||||||
.unwrap();
|
|
||||||
pass_pipelines.push(name.to_string());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
asset::{AssetStorage, Handle},
|
asset::{AssetStorage, Handle},
|
||||||
render::{render_graph_2::RenderGraph, Shader},
|
render::{render_graph_2::RenderGraph, Shader, ShaderStages},
|
||||||
};
|
};
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
use super::PipelineDescriptor;
|
||||||
|
|
||||||
pub struct Renderable {
|
pub struct Renderable {
|
||||||
pub is_visible: bool,
|
pub is_visible: bool,
|
||||||
pub shaders: Vec<Handle<Shader>>,
|
pub pipelines: Vec<Handle<PipelineDescriptor>>,
|
||||||
pub shader_defs: HashSet<String>,
|
pub shader_defs: HashSet<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +16,7 @@ impl Default for Renderable {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Renderable {
|
Renderable {
|
||||||
is_visible: true,
|
is_visible: true,
|
||||||
shaders: Vec::new(),
|
pipelines: Vec::new(),
|
||||||
shader_defs: HashSet::new(),
|
shader_defs: HashSet::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,24 +54,28 @@ pub fn update_shader_assignments(world: &mut World, render_graph: &mut RenderGra
|
||||||
let shader_assignments = world.resources.get_mut::<ShaderAssignments>().unwrap();
|
let shader_assignments = world.resources.get_mut::<ShaderAssignments>().unwrap();
|
||||||
let mut compiled_shader_map = world.resources.get_mut::<CompiledShaderMap>().unwrap();
|
let mut compiled_shader_map = world.resources.get_mut::<CompiledShaderMap>().unwrap();
|
||||||
let mut shader_storage = world.resources.get_mut::<AssetStorage<Shader>>().unwrap();
|
let mut shader_storage = world.resources.get_mut::<AssetStorage<Shader>>().unwrap();
|
||||||
|
let pipeline_descriptor_storage = world.resources.get_mut::<AssetStorage<PipelineDescriptor>>().unwrap();
|
||||||
for (entity, renderable) in <Read<Renderable>>::query().iter_entities(world) {
|
for (entity, renderable) in <Read<Renderable>>::query().iter_entities(world) {
|
||||||
for shader in renderable.shaders.iter() {
|
for pipeline_handle in renderable.pipelines.iter() {
|
||||||
if let None = compiled_shader_map.source_to_compiled.get(shader) {
|
let pipeline_descriptor = pipeline_descriptor_storage.get(pipeline_handle).unwrap();
|
||||||
compiled_shader_map
|
for shader_handle in pipeline_descriptor.shader_stages.iter() {
|
||||||
.source_to_compiled
|
if let None = compiled_shader_map.source_to_compiled.get(shader_handle) {
|
||||||
.insert(shader.clone(), Vec::new());
|
compiled_shader_map
|
||||||
}
|
.source_to_compiled
|
||||||
|
.insert(shader_handle.clone(), Vec::new());
|
||||||
|
}
|
||||||
|
|
||||||
let compiled_shaders = compiled_shader_map.source_to_compiled.get_mut(shader).unwrap();
|
let compiled_shaders = compiled_shader_map.source_to_compiled.get_mut(shader_handle).unwrap();
|
||||||
if let None = compiled_shaders.iter().find(|(shader_defs, _shader)| *shader_defs == renderable.shader_defs) {
|
if let None = compiled_shaders.iter().find(|(shader_defs, _shader)| *shader_defs == renderable.shader_defs) {
|
||||||
let shader_resource = shader_storage.get(shader).unwrap();
|
let shader_resource = shader_storage.get(shader_handle).unwrap();
|
||||||
let shader_def_vec = renderable.shader_defs.iter().cloned().collect::<Vec<String>>();
|
let shader_def_vec = renderable.shader_defs.iter().cloned().collect::<Vec<String>>();
|
||||||
let compiled_shader = shader_resource.get_spirv_shader(Some(&shader_def_vec));
|
let compiled_shader = shader_resource.get_spirv_shader(Some(&shader_def_vec));
|
||||||
compiled_shaders.push((renderable.shader_defs.clone(), shader.clone()));
|
compiled_shaders.push((renderable.shader_defs.clone(), shader_handle.clone()));
|
||||||
let compiled_shader_handle = shader_storage.add(compiled_shader);
|
let compiled_shader_handle = shader_storage.add(compiled_shader);
|
||||||
// TODO: collecting assigments in a map means they won't be removed when the macro changes
|
// TODO: collecting assigments in a map means they won't be removed when the macro changes
|
||||||
// TODO: need to somehow grab base shader's pipeline, then copy it
|
// TODO: need to somehow grab base shader's pipeline, then copy it
|
||||||
// shader_assignments.assignments.insert()
|
// shader_assignments.assignments.insert()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
|
asset::{AssetStorage, Handle},
|
||||||
legion::prelude::*,
|
legion::prelude::*,
|
||||||
render::{Shader, render_graph_2::{
|
render::{
|
||||||
resource_name, update_shader_assignments, BindGroup, BindType, DynamicUniformBufferInfo,
|
render_graph_2::{
|
||||||
PassDescriptor, PipelineDescriptor, RenderGraph, RenderPass,
|
resource_name, update_shader_assignments, BindGroup, BindType,
|
||||||
RenderPassColorAttachmentDescriptor, RenderPassDepthStencilAttachmentDescriptor, Renderer,
|
DynamicUniformBufferInfo, PassDescriptor, PipelineDescriptor, RenderGraph, RenderPass,
|
||||||
ResourceInfo, ShaderUniforms, TextureDescriptor,
|
RenderPassColorAttachmentDescriptor, RenderPassDepthStencilAttachmentDescriptor,
|
||||||
}},
|
Renderer, ResourceInfo, TextureDescriptor,
|
||||||
|
},
|
||||||
|
Shader,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, ops::Deref};
|
use std::{collections::HashMap, ops::Deref};
|
||||||
|
|
||||||
|
@ -15,7 +19,7 @@ pub struct WgpuRenderer {
|
||||||
pub surface: Option<wgpu::Surface>,
|
pub surface: Option<wgpu::Surface>,
|
||||||
pub encoder: Option<wgpu::CommandEncoder>,
|
pub encoder: Option<wgpu::CommandEncoder>,
|
||||||
pub swap_chain_descriptor: wgpu::SwapChainDescriptor,
|
pub swap_chain_descriptor: wgpu::SwapChainDescriptor,
|
||||||
pub render_pipelines: HashMap<String, wgpu::RenderPipeline>,
|
pub render_pipelines: HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>,
|
||||||
pub buffers: HashMap<String, wgpu::Buffer>,
|
pub buffers: HashMap<String, wgpu::Buffer>,
|
||||||
pub textures: HashMap<String, wgpu::TextureView>,
|
pub textures: HashMap<String, wgpu::TextureView>,
|
||||||
pub resource_info: HashMap<String, ResourceInfo>,
|
pub resource_info: HashMap<String, ResourceInfo>,
|
||||||
|
@ -69,12 +73,14 @@ impl WgpuRenderer {
|
||||||
pipeline_descriptor: &mut PipelineDescriptor,
|
pipeline_descriptor: &mut PipelineDescriptor,
|
||||||
bind_group_layouts: &mut HashMap<u64, wgpu::BindGroupLayout>,
|
bind_group_layouts: &mut HashMap<u64, wgpu::BindGroupLayout>,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
|
vertex_shader: &Shader,
|
||||||
|
fragment_shader: Option<&Shader>,
|
||||||
) -> wgpu::RenderPipeline {
|
) -> wgpu::RenderPipeline {
|
||||||
let vertex_shader_module = Self::create_shader_module(device, &pipeline_descriptor
|
let vertex_shader_module = Self::create_shader_module(device, vertex_shader, None);
|
||||||
.shader_stages
|
let fragment_shader_module = match fragment_shader {
|
||||||
.vertex, None);
|
Some(fragment_shader) => {
|
||||||
let fragment_shader_module = match pipeline_descriptor.shader_stages.fragment {
|
Some(Self::create_shader_module(device, fragment_shader, None))
|
||||||
Some(ref fragment_shader) => Some(Self::create_shader_module(device, fragment_shader, None)),
|
}
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -121,10 +127,10 @@ impl WgpuRenderer {
|
||||||
layout: &pipeline_layout,
|
layout: &pipeline_layout,
|
||||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||||
module: &vertex_shader_module,
|
module: &vertex_shader_module,
|
||||||
entry_point: &pipeline_descriptor.shader_stages.vertex.entry_point,
|
entry_point: &vertex_shader.entry_point,
|
||||||
},
|
},
|
||||||
fragment_stage: match pipeline_descriptor.shader_stages.fragment {
|
fragment_stage: match fragment_shader {
|
||||||
Some(ref fragment_shader) => Some(wgpu::ProgrammableStageDescriptor {
|
Some(fragment_shader) => Some(wgpu::ProgrammableStageDescriptor {
|
||||||
entry_point: &fragment_shader.entry_point,
|
entry_point: &fragment_shader.entry_point,
|
||||||
module: fragment_shader_module.as_ref().unwrap(),
|
module: fragment_shader_module.as_ref().unwrap(),
|
||||||
}),
|
}),
|
||||||
|
@ -303,115 +309,11 @@ impl WgpuRenderer {
|
||||||
bind_group_id
|
bind_group_id
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove me
|
pub fn create_shader_module(
|
||||||
#[allow(dead_code)]
|
device: &wgpu::Device,
|
||||||
fn setup_dynamic_entity_shader_uniforms(
|
shader: &Shader,
|
||||||
&mut self,
|
macros: Option<&[String]>,
|
||||||
world: &World,
|
) -> wgpu::ShaderModule {
|
||||||
render_graph: &RenderGraph,
|
|
||||||
encoder: &mut wgpu::CommandEncoder,
|
|
||||||
) {
|
|
||||||
// retrieve all uniforms buffers that aren't aleady set. these are "dynamic" uniforms, which are set by the user in ShaderUniforms
|
|
||||||
// TODO: this breaks down in multiple ways:
|
|
||||||
// (1) resource_info will be set after the first run so this won't update.
|
|
||||||
// (2) if we create new buffers, the old bind groups will be invalid
|
|
||||||
for pipeline in render_graph.pipeline_descriptors.values() {
|
|
||||||
for bind_group in pipeline.pipeline_layout.bind_groups.iter() {
|
|
||||||
for binding in bind_group.bindings.iter() {
|
|
||||||
// if let None = self.resource_info.get(&binding.name) {
|
|
||||||
if let BindType::Uniform { dynamic: true, .. } = &binding.bind_type {
|
|
||||||
if self.dynamic_uniform_buffer_info.contains_key(&binding.name) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.dynamic_uniform_buffer_info.insert(
|
|
||||||
binding.name.to_string(),
|
|
||||||
DynamicUniformBufferInfo {
|
|
||||||
capacity: 0,
|
|
||||||
count: 0,
|
|
||||||
size: binding.bind_type.get_uniform_size().unwrap(),
|
|
||||||
indices: HashMap::new(),
|
|
||||||
offsets: HashMap::new(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// count the number of entities providing each uniform
|
|
||||||
for (name, info) in self.dynamic_uniform_buffer_info.iter_mut() {
|
|
||||||
info.count = 0;
|
|
||||||
for (entity, shader_uniforms) in <Read<ShaderUniforms>>::query().iter_entities(world) {
|
|
||||||
if let Some(_) = shader_uniforms.get_uniform_info(world, entity, name) {
|
|
||||||
info.count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate uniform buffers
|
|
||||||
for (name, info) in self.dynamic_uniform_buffer_info.iter_mut() {
|
|
||||||
if self.buffers.contains_key(name) && info.count < info.capacity {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.count >= info.capacity && info.capacity != 0 {
|
|
||||||
panic!("resizing dynamic uniform buffers isn't supported yet. we still need to support updating bind groups");
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate enough space for twice as many entities as there are currently;
|
|
||||||
info.capacity = info.count * 2;
|
|
||||||
let size = wgpu::BIND_BUFFER_ALIGNMENT * info.capacity;
|
|
||||||
|
|
||||||
// TODO: remove this code duplication in favor of self.create_buffer(). this will likely require a refactor
|
|
||||||
// the following is a flattening of the content in self.create_buffer(), which can't be called because
|
|
||||||
// of rust's ownership rules. sometimes rust makes me unhappy
|
|
||||||
|
|
||||||
let buffer_usage = wgpu::BufferUsage::COPY_DST | wgpu::BufferUsage::UNIFORM;
|
|
||||||
let buffer = self.device.create_buffer(&wgpu::BufferDescriptor {
|
|
||||||
size,
|
|
||||||
usage: buffer_usage,
|
|
||||||
});
|
|
||||||
|
|
||||||
self.resource_info.insert(
|
|
||||||
name.to_string(),
|
|
||||||
ResourceInfo::Buffer { buffer_usage, size },
|
|
||||||
);
|
|
||||||
|
|
||||||
self.buffers.insert(name.to_string(), buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy entity uniform data to buffers
|
|
||||||
for (name, info) in self.dynamic_uniform_buffer_info.iter_mut() {
|
|
||||||
let size = wgpu::BIND_BUFFER_ALIGNMENT * info.count;
|
|
||||||
let mapped = self
|
|
||||||
.device
|
|
||||||
.create_buffer_mapped(size as usize, wgpu::BufferUsage::COPY_SRC);
|
|
||||||
let alignment = wgpu::BIND_BUFFER_ALIGNMENT as usize;
|
|
||||||
let mut offset = 0usize;
|
|
||||||
|
|
||||||
for (i, (entity, shader_uniforms)) in <Read<ShaderUniforms>>::query()
|
|
||||||
.iter_entities(world)
|
|
||||||
.enumerate()
|
|
||||||
{
|
|
||||||
// TODO: check if index has changed. if it has, then entity should be updated
|
|
||||||
// TODO: only mem-map entities if their data has changed
|
|
||||||
info.offsets.insert(entity, offset as u64);
|
|
||||||
info.indices.insert(i, entity);
|
|
||||||
if let Some(bytes) = shader_uniforms.get_uniform_bytes(world, entity, name) {
|
|
||||||
mapped.data[offset..(offset + bytes.len())].copy_from_slice(bytes.as_slice());
|
|
||||||
offset += alignment;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let temp_buffer = mapped.finish();
|
|
||||||
let uniform_buffer = self.buffers.get(name);
|
|
||||||
encoder.copy_buffer_to_buffer(&temp_buffer, 0, uniform_buffer.unwrap(), 0, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_shader_module(device: &wgpu::Device, shader: &Shader, macros: Option<&[String]>) -> wgpu::ShaderModule {
|
|
||||||
device.create_shader_module(&shader.get_spirv(macros))
|
device.create_shader_module(&shader.get_spirv(macros))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -489,16 +391,38 @@ impl Renderer for WgpuRenderer {
|
||||||
// self.setup_dynamic_entity_shader_uniforms(world, render_graph, &mut encoder);
|
// self.setup_dynamic_entity_shader_uniforms(world, render_graph, &mut encoder);
|
||||||
|
|
||||||
// setup, pipelines, bind groups, and resources
|
// setup, pipelines, bind groups, and resources
|
||||||
for (pipeline_name, pipeline_descriptor) in render_graph.pipeline_descriptors.iter_mut() {
|
let mut pipeline_storage = world
|
||||||
|
.resources
|
||||||
|
.get_mut::<AssetStorage<PipelineDescriptor>>()
|
||||||
|
.unwrap();
|
||||||
|
let shader_storage = world.resources.get::<AssetStorage<Shader>>().unwrap();
|
||||||
|
|
||||||
|
for pipeline_descriptor_handle in render_graph.pipeline_descriptors.iter() {
|
||||||
|
let pipeline_descriptor = pipeline_storage
|
||||||
|
.get_mut(pipeline_descriptor_handle)
|
||||||
|
.unwrap();
|
||||||
// create pipelines
|
// create pipelines
|
||||||
if let None = self.render_pipelines.get(pipeline_name) {
|
if !self
|
||||||
|
.render_pipelines
|
||||||
|
.contains_key(pipeline_descriptor_handle)
|
||||||
|
{
|
||||||
|
let vertex_shader = shader_storage
|
||||||
|
.get(&pipeline_descriptor.shader_stages.vertex)
|
||||||
|
.unwrap();
|
||||||
|
let fragment_shader = pipeline_descriptor
|
||||||
|
.shader_stages
|
||||||
|
.fragment
|
||||||
|
.as_ref()
|
||||||
|
.map(|handle| &*shader_storage.get(&handle).unwrap());
|
||||||
let render_pipeline = WgpuRenderer::create_render_pipeline(
|
let render_pipeline = WgpuRenderer::create_render_pipeline(
|
||||||
pipeline_descriptor,
|
pipeline_descriptor,
|
||||||
&mut self.bind_group_layouts,
|
&mut self.bind_group_layouts,
|
||||||
&self.device,
|
&self.device,
|
||||||
|
vertex_shader,
|
||||||
|
fragment_shader,
|
||||||
);
|
);
|
||||||
self.render_pipelines
|
self.render_pipelines
|
||||||
.insert(pipeline_name.to_string(), render_pipeline);
|
.insert(pipeline_descriptor_handle.clone(), render_pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create bind groups
|
// create bind groups
|
||||||
|
@ -512,21 +436,18 @@ impl Renderer for WgpuRenderer {
|
||||||
let mut render_pass = self.create_render_pass(pass_descriptor, &mut encoder, &frame);
|
let mut render_pass = self.create_render_pass(pass_descriptor, &mut encoder, &frame);
|
||||||
if let Some(pass_pipelines) = render_graph.pass_pipelines.get(pass_name) {
|
if let Some(pass_pipelines) = render_graph.pass_pipelines.get(pass_name) {
|
||||||
for pass_pipeline in pass_pipelines.iter() {
|
for pass_pipeline in pass_pipelines.iter() {
|
||||||
if let Some(pipeline_descriptor) =
|
let pipeline_descriptor = pipeline_storage.get(pass_pipeline).unwrap();
|
||||||
render_graph.pipeline_descriptors.get(pass_pipeline)
|
let render_pipeline = self.render_pipelines.get(pass_pipeline).unwrap();
|
||||||
{
|
render_pass.set_pipeline(render_pipeline);
|
||||||
let render_pipeline = self.render_pipelines.get(pass_pipeline).unwrap();
|
|
||||||
render_pass.set_pipeline(render_pipeline);
|
|
||||||
|
|
||||||
let mut render_pass = WgpuRenderPass {
|
let mut render_pass = WgpuRenderPass {
|
||||||
render_pass: &mut render_pass,
|
render_pass: &mut render_pass,
|
||||||
renderer: self,
|
renderer: self,
|
||||||
pipeline_descriptor,
|
pipeline_descriptor,
|
||||||
};
|
};
|
||||||
|
|
||||||
for draw_target in pipeline_descriptor.draw_targets.iter() {
|
for draw_target in pipeline_descriptor.draw_targets.iter() {
|
||||||
draw_target(world, &mut render_pass);
|
draw_target(world, &mut render_pass);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::asset::Handle;
|
||||||
use std::marker::Copy;
|
use std::marker::Copy;
|
||||||
|
|
||||||
#[derive(Hash, Eq, PartialEq, Copy, Clone)]
|
#[derive(Hash, Eq, PartialEq, Copy, Clone)]
|
||||||
|
@ -69,9 +70,7 @@ impl Shader {
|
||||||
pub fn get_spirv(&self, macros: Option<&[String]>) -> Vec<u32> {
|
pub fn get_spirv(&self, macros: Option<&[String]>) -> Vec<u32> {
|
||||||
match self.source {
|
match self.source {
|
||||||
ShaderSource::Spirv(ref bytes) => bytes.clone(),
|
ShaderSource::Spirv(ref bytes) => bytes.clone(),
|
||||||
ShaderSource::Glsl(ref source) => {
|
ShaderSource::Glsl(ref source) => glsl_to_spirv(&source, self.stage, macros),
|
||||||
glsl_to_spirv(&source, self.stage, macros)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,15 +84,44 @@ impl Shader {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ShaderStages {
|
pub struct ShaderStages {
|
||||||
pub vertex: Shader,
|
pub vertex: Handle<Shader>,
|
||||||
pub fragment: Option<Shader>,
|
pub fragment: Option<Handle<Shader>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShaderStages {
|
impl ShaderStages {
|
||||||
pub fn new(vertex_shader: Shader) -> Self {
|
pub fn new(vertex_shader: Handle<Shader>) -> Self {
|
||||||
ShaderStages {
|
ShaderStages {
|
||||||
vertex: vertex_shader,
|
vertex: vertex_shader,
|
||||||
fragment: None,
|
fragment: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> ShaderStagesIter {
|
||||||
|
ShaderStagesIter {
|
||||||
|
shader_stages: self,
|
||||||
|
index: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ShaderStagesIter<'a> {
|
||||||
|
pub shader_stages: &'a ShaderStages,
|
||||||
|
pub index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for ShaderStagesIter<'a> {
|
||||||
|
type Item = &'a Handle<Shader>;
|
||||||
|
fn next(&mut self) -> Option<&'a Handle<Shader>> {
|
||||||
|
match self.index {
|
||||||
|
0 => Some(&self.shader_stages.vertex),
|
||||||
|
1 => {
|
||||||
|
if let Some(ref fragment) = self.shader_stages.fragment {
|
||||||
|
Some(fragment)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue