pipeline builder
This commit is contained in:
		
							parent
							
								
									3a674394b9
								
							
						
					
					
						commit
						d9bd2d4f15
					
				| @ -2,14 +2,15 @@ mod pipeline; | |||||||
| 
 | 
 | ||||||
| pub use pipeline::*; | pub use pipeline::*; | ||||||
| 
 | 
 | ||||||
|  | use crate::prelude::*; | ||||||
| use crate::{asset::Texture, legion::{prelude::{Entity, World}, borrow::{Ref, RefMap}}, render::Albedo}; | use crate::{asset::Texture, legion::{prelude::{Entity, World}, borrow::{Ref, RefMap}}, render::Albedo}; | ||||||
| use std::{collections::{HashMap, HashSet}, ops::Deref}; | use std::collections::HashMap; | ||||||
| 
 | 
 | ||||||
| pub enum ShaderValue<'a> { | pub enum ShaderValue<'a> { | ||||||
|     Int(u32), |     Int(u32), | ||||||
|     Float(f32), |     Float(f32), | ||||||
|     Vec4(crate::math::Vec4), |     Vec4(Vec4), | ||||||
|     Texture(&'a crate::asset::Handle<Texture>), |     Texture(&'a Handle<Texture>), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type ShaderMaterialSelector = fn(Entity, &World) -> Option<RefMap<&dyn ShaderMaterial>>; | type ShaderMaterialSelector = fn(Entity, &World) -> Option<RefMap<&dyn ShaderMaterial>>; | ||||||
| @ -88,12 +89,20 @@ enum ResourceType { | |||||||
| // updates resources based on events like "resize" or "update"
 | // updates resources based on events like "resize" or "update"
 | ||||||
| // if there are no resources in use, dont run allocate resource provider resources on gpu
 | // if there are no resources in use, dont run allocate resource provider resources on gpu
 | ||||||
| trait ResourceProvider { | trait ResourceProvider { | ||||||
|   fn get_resources() -> Vec<String>; |   fn get_resources(&self) -> &[Resource]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // holds on to passes, pipeline descriptions, instances
 | // holds on to passes, pipeline descriptions, instances
 | ||||||
| // passes: shadow, forward
 | // passes: shadow, forward
 | ||||||
| struct RenderGraph; | struct RenderGraph { | ||||||
|  |   pipeline_definitions: HashMap<String, PipelineDefinition>, | ||||||
|  |   pipeline_instances: HashMap<String, wgpu::RenderPipeline>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct RenderGraphBuilder { | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* | /* | ||||||
| RenderGraph::build() | RenderGraph::build() | ||||||
| .AddPass("forward", Pass { | .AddPass("forward", Pass { | ||||||
| @ -127,20 +136,35 @@ RenderGraph::build() | |||||||
| ) | ) | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| // A set of draw calls. ex: get + draw meshes, get + draw instanced meshes, draw ui meshes, etc 
 | pub struct RenderPassColorAttachmentDescription { | ||||||
| // Mesh target
 |   /// The actual color attachment.
 | ||||||
| trait DrawTarget { |   pub attachment: String, | ||||||
|     fn draw(device: &wgpu::Device); | 
 | ||||||
|  |   /// The resolve target for this color attachment, if any.
 | ||||||
|  |   pub resolve_target: Option<String>, | ||||||
|  | 
 | ||||||
|  |   /// The beginning-of-pass load operation for this color attachment.
 | ||||||
|  |   pub load_op: wgpu::LoadOp, | ||||||
|  | 
 | ||||||
|  |   /// The end-of-pass store operation for this color attachment.
 | ||||||
|  |   pub store_op: wgpu::StoreOp, | ||||||
|  | 
 | ||||||
|  |   /// The color that will be assigned to every pixel of this attachment when cleared.
 | ||||||
|  |   pub clear_color: wgpu::Color, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // a texture that is rendered to. TextureView or SwapChain
 | pub struct RenderPassDepthStencilAttachmentDescription { | ||||||
| struct RenderTarget; |     pub attachment: String, | ||||||
|  |     pub depth_load_op: wgpu::LoadOp, | ||||||
|  |     pub depth_store_op: wgpu::StoreOp, | ||||||
|  |     pub clear_depth: f32, | ||||||
|  |     pub stencil_load_op: wgpu::LoadOp, | ||||||
|  |     pub stencil_store_op: wgpu::StoreOp, | ||||||
|  |     pub clear_stencil: u32, | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| // A set of pipeline bindings and draw calls with color and depth outputs
 | // A set of pipeline bindings and draw calls with color and depth outputs
 | ||||||
| struct Pass; | struct Pass { | ||||||
| 
 |   color_attachments: Vec<RenderPassColorAttachmentDescription>, | ||||||
| // A pipeline description (original shaders)
 |   depth_stencil_attachment: Option<RenderPassDepthStencilAttachmentDescription>, | ||||||
| struct PipelineDefinition; | } | ||||||
| 
 |  | ||||||
| // A specific instance of a pipeline definition
 |  | ||||||
| struct Pipeline; |  | ||||||
| @ -1,4 +1,14 @@ | |||||||
| use crate::render::shader::ShaderStages; | use crate::{ | ||||||
|  |     legion::prelude::World, | ||||||
|  |     render::shader::{Shader, ShaderStages}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // A set of draw calls. ex: get + draw meshes, get + draw instanced meshes, draw ui meshes, etc
 | ||||||
|  | // Mesh target
 | ||||||
|  | // trait DrawTarget {
 | ||||||
|  | //     fn draw(device: &wgpu::Device);
 | ||||||
|  | // }
 | ||||||
|  | type DrawTarget = fn(world: &World, device: &wgpu::Device); | ||||||
| 
 | 
 | ||||||
| pub struct VertexBufferDefinition { | pub struct VertexBufferDefinition { | ||||||
|     pub stride: wgpu::BufferAddress, |     pub stride: wgpu::BufferAddress, | ||||||
| @ -17,6 +27,7 @@ impl<'a> Into<wgpu::VertexBufferDescriptor<'a>> for &'a VertexBufferDefinition { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct PipelineDefinition { | pub struct PipelineDefinition { | ||||||
|  |     pub draw_targets: Vec<DrawTarget>, | ||||||
|     pub shader_stages: ShaderStages, |     pub shader_stages: ShaderStages, | ||||||
|     pub rasterization_state: Option<wgpu::RasterizationStateDescriptor>, |     pub rasterization_state: Option<wgpu::RasterizationStateDescriptor>, | ||||||
| 
 | 
 | ||||||
| @ -49,6 +60,30 @@ pub struct PipelineDefinition { | |||||||
|     pub alpha_to_coverage_enabled: bool, |     pub alpha_to_coverage_enabled: bool, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | impl PipelineDefinition { | ||||||
|  |     fn new(vertex_shader: Shader) -> Self { | ||||||
|  |         PipelineDefinition { | ||||||
|  |             color_states: Vec::new(), | ||||||
|  |             depth_stencil_state: None, | ||||||
|  |             draw_targets: Vec::new(), | ||||||
|  |             shader_stages: ShaderStages::new(vertex_shader), | ||||||
|  |             vertex_buffer_definitions: Vec::new(), | ||||||
|  |             rasterization_state: Some(wgpu::RasterizationStateDescriptor { | ||||||
|  |                 front_face: wgpu::FrontFace::Ccw, | ||||||
|  |                 cull_mode: wgpu::CullMode::Back, | ||||||
|  |                 depth_bias: 0, | ||||||
|  |                 depth_bias_slope_scale: 0.0, | ||||||
|  |                 depth_bias_clamp: 0.0, | ||||||
|  |             }), | ||||||
|  |             primitive_topology: wgpu::PrimitiveTopology::TriangleList, | ||||||
|  |             index_format: wgpu::IndexFormat::Uint16, | ||||||
|  |             sample_count: 1, | ||||||
|  |             sample_mask: !0, | ||||||
|  |             alpha_to_coverage_enabled: false, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| impl PipelineDefinition { | impl PipelineDefinition { | ||||||
|     pub fn create_render_pipeline(&self, device: &wgpu::Device) -> wgpu::RenderPipeline { |     pub fn create_render_pipeline(&self, device: &wgpu::Device) -> wgpu::RenderPipeline { | ||||||
|         let vertex_shader_module = self.shader_stages.vertex.create_shader_module(device); |         let vertex_shader_module = self.shader_stages.vertex.create_shader_module(device); | ||||||
| @ -57,9 +92,7 @@ impl PipelineDefinition { | |||||||
|             None => None, |             None => None, | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         let pipeline_layout = |         let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { | ||||||
|                 device |  | ||||||
|                 .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { |  | ||||||
|             bind_group_layouts: &[], |             bind_group_layouts: &[], | ||||||
|         }); |         }); | ||||||
|         let render_pipeline_descriptor = wgpu::RenderPipelineDescriptor { |         let render_pipeline_descriptor = wgpu::RenderPipelineDescriptor { | ||||||
| @ -80,7 +113,11 @@ impl PipelineDefinition { | |||||||
|             color_states: &self.color_states, |             color_states: &self.color_states, | ||||||
|             depth_stencil_state: self.depth_stencil_state.clone(), |             depth_stencil_state: self.depth_stencil_state.clone(), | ||||||
|             index_format: self.index_format, |             index_format: self.index_format, | ||||||
|             vertex_buffers: &self.vertex_buffer_definitions.iter().map(|v| v.into()).collect::<Vec<wgpu::VertexBufferDescriptor>>(), |             vertex_buffers: &self | ||||||
|  |                 .vertex_buffer_definitions | ||||||
|  |                 .iter() | ||||||
|  |                 .map(|v| v.into()) | ||||||
|  |                 .collect::<Vec<wgpu::VertexBufferDescriptor>>(), | ||||||
|             sample_count: self.sample_count, |             sample_count: self.sample_count, | ||||||
|             sample_mask: self.sample_mask, |             sample_mask: self.sample_mask, | ||||||
|             alpha_to_coverage_enabled: self.alpha_to_coverage_enabled, |             alpha_to_coverage_enabled: self.alpha_to_coverage_enabled, | ||||||
| @ -88,4 +125,78 @@ impl PipelineDefinition { | |||||||
| 
 | 
 | ||||||
|         device.create_render_pipeline(&render_pipeline_descriptor) |         device.create_render_pipeline(&render_pipeline_descriptor) | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     pub fn build(vertex_shader: Shader) -> PipelineBuilder { | ||||||
|  |         PipelineBuilder::new(vertex_shader) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub struct PipelineBuilder { | ||||||
|  |     pipeline: PipelineDefinition, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl PipelineBuilder { | ||||||
|  |     pub fn new(vertex_shader: Shader) -> Self { | ||||||
|  |         PipelineBuilder { | ||||||
|  |             pipeline: PipelineDefinition::new(vertex_shader), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn with_fragment_shader(mut self, fragment_shader: Shader) -> Self { | ||||||
|  |         self.pipeline.shader_stages.fragment = Some(fragment_shader); | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn with_color_state(mut self, color_state_descriptor: wgpu::ColorStateDescriptor) -> Self { | ||||||
|  |         self.pipeline.color_states.push(color_state_descriptor); | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn with_depth_stencil_state(mut self, depth_stencil_state: wgpu::DepthStencilStateDescriptor) -> Self { | ||||||
|  |         if let Some(_) = self.pipeline.depth_stencil_state { | ||||||
|  |             panic!("Depth stencil state has already been set"); | ||||||
|  |         } | ||||||
|  |         self.pipeline.depth_stencil_state = Some(depth_stencil_state); | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn with_vertex_buffer_definition(mut self, vertex_buffer_definition: VertexBufferDefinition) -> Self { | ||||||
|  |         self.pipeline.vertex_buffer_definitions.push(vertex_buffer_definition); | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn with_index_format(mut self, index_format: wgpu::IndexFormat) -> Self { | ||||||
|  |         self.pipeline.index_format = index_format; | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn with_draw_target(mut self, draw_target: DrawTarget) -> Self { | ||||||
|  |         self.pipeline.draw_targets.push(draw_target); | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn with_rasterization_state(mut self, rasterization_state: wgpu::RasterizationStateDescriptor) -> Self { | ||||||
|  |         self.pipeline.rasterization_state = Some(rasterization_state); | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn with_primitive_topology(mut self, primitive_topology: wgpu::PrimitiveTopology) -> Self { | ||||||
|  |         self.pipeline.primitive_topology = primitive_topology; | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn with_sample_count(mut self, sample_count: u32) -> Self { | ||||||
|  |         self.pipeline.sample_count = sample_count; | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn with_alpha_to_coverage_enabled(mut self, alpha_to_coverage_enabled: bool) -> Self { | ||||||
|  |         self.pipeline.alpha_to_coverage_enabled = alpha_to_coverage_enabled; | ||||||
|  |         self | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn with_sample_mask(mut self, sample_mask: u32) -> Self { | ||||||
|  |         self.pipeline.sample_mask = sample_mask; | ||||||
|  |         self | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -66,3 +66,12 @@ pub struct ShaderStages { | |||||||
|     pub vertex: Shader, |     pub vertex: Shader, | ||||||
|     pub fragment: Option<Shader>, |     pub fragment: Option<Shader>, | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | impl ShaderStages { | ||||||
|  |     pub fn new(vertex_shader: Shader) -> Self { | ||||||
|  |         ShaderStages { | ||||||
|  |             vertex: vertex_shader, | ||||||
|  |             fragment: None, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Carter Anderson
						Carter Anderson