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,11 +92,9 @@ impl PipelineDefinition {
|
|||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let pipeline_layout =
|
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
device
|
bind_group_layouts: &[],
|
||||||
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
});
|
||||||
bind_group_layouts: &[],
|
|
||||||
});
|
|
||||||
let render_pipeline_descriptor = wgpu::RenderPipelineDescriptor {
|
let render_pipeline_descriptor = wgpu::RenderPipelineDescriptor {
|
||||||
layout: &pipeline_layout,
|
layout: &pipeline_layout,
|
||||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||||
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,4 +65,13 @@ impl Shader {
|
|||||||
pub struct ShaderStages {
|
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