mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
pipeline builder
This commit is contained in:
parent
3a674394b9
commit
d9bd2d4f15
3 changed files with 169 additions and 25 deletions
|
@ -2,14 +2,15 @@ mod pipeline;
|
|||
|
||||
pub use pipeline::*;
|
||||
|
||||
use crate::prelude::*;
|
||||
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> {
|
||||
Int(u32),
|
||||
Float(f32),
|
||||
Vec4(crate::math::Vec4),
|
||||
Texture(&'a crate::asset::Handle<Texture>),
|
||||
Vec4(Vec4),
|
||||
Texture(&'a Handle<Texture>),
|
||||
}
|
||||
|
||||
type ShaderMaterialSelector = fn(Entity, &World) -> Option<RefMap<&dyn ShaderMaterial>>;
|
||||
|
@ -88,12 +89,20 @@ enum ResourceType {
|
|||
// updates resources based on events like "resize" or "update"
|
||||
// if there are no resources in use, dont run allocate resource provider resources on gpu
|
||||
trait ResourceProvider {
|
||||
fn get_resources() -> Vec<String>;
|
||||
fn get_resources(&self) -> &[Resource];
|
||||
}
|
||||
|
||||
// holds on to passes, pipeline descriptions, instances
|
||||
// passes: shadow, forward
|
||||
struct RenderGraph;
|
||||
struct RenderGraph {
|
||||
pipeline_definitions: HashMap<String, PipelineDefinition>,
|
||||
pipeline_instances: HashMap<String, wgpu::RenderPipeline>,
|
||||
}
|
||||
|
||||
struct RenderGraphBuilder {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
RenderGraph::build()
|
||||
.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
|
||||
// Mesh target
|
||||
trait DrawTarget {
|
||||
fn draw(device: &wgpu::Device);
|
||||
pub struct RenderPassColorAttachmentDescription {
|
||||
/// The actual color attachment.
|
||||
pub attachment: String,
|
||||
|
||||
/// 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
|
||||
struct RenderTarget;
|
||||
pub struct RenderPassDepthStencilAttachmentDescription {
|
||||
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
|
||||
struct Pass;
|
||||
|
||||
// A pipeline description (original shaders)
|
||||
struct PipelineDefinition;
|
||||
|
||||
// A specific instance of a pipeline definition
|
||||
struct Pipeline;
|
||||
struct Pass {
|
||||
color_attachments: Vec<RenderPassColorAttachmentDescription>,
|
||||
depth_stencil_attachment: Option<RenderPassDepthStencilAttachmentDescription>,
|
||||
}
|
|
@ -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 stride: wgpu::BufferAddress,
|
||||
|
@ -17,6 +27,7 @@ impl<'a> Into<wgpu::VertexBufferDescriptor<'a>> for &'a VertexBufferDefinition {
|
|||
}
|
||||
|
||||
pub struct PipelineDefinition {
|
||||
pub draw_targets: Vec<DrawTarget>,
|
||||
pub shader_stages: ShaderStages,
|
||||
pub rasterization_state: Option<wgpu::RasterizationStateDescriptor>,
|
||||
|
||||
|
@ -49,6 +60,30 @@ pub struct PipelineDefinition {
|
|||
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 {
|
||||
pub fn create_render_pipeline(&self, device: &wgpu::Device) -> wgpu::RenderPipeline {
|
||||
let vertex_shader_module = self.shader_stages.vertex.create_shader_module(device);
|
||||
|
@ -57,11 +92,9 @@ impl PipelineDefinition {
|
|||
None => None,
|
||||
};
|
||||
|
||||
let pipeline_layout =
|
||||
device
|
||||
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
bind_group_layouts: &[],
|
||||
});
|
||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
bind_group_layouts: &[],
|
||||
});
|
||||
let render_pipeline_descriptor = wgpu::RenderPipelineDescriptor {
|
||||
layout: &pipeline_layout,
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
|
@ -80,7 +113,11 @@ impl PipelineDefinition {
|
|||
color_states: &self.color_states,
|
||||
depth_stencil_state: self.depth_stencil_state.clone(),
|
||||
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_mask: self.sample_mask,
|
||||
alpha_to_coverage_enabled: self.alpha_to_coverage_enabled,
|
||||
|
@ -88,4 +125,78 @@ impl PipelineDefinition {
|
|||
|
||||
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 vertex: Shader,
|
||||
pub fragment: Option<Shader>,
|
||||
}
|
||||
|
||||
impl ShaderStages {
|
||||
pub fn new(vertex_shader: Shader) -> Self {
|
||||
ShaderStages {
|
||||
vertex: vertex_shader,
|
||||
fragment: None,
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue