From 83f360600075d56416a53eb8d6ed7979c33585fd Mon Sep 17 00:00:00 2001 From: Jarrod Doyle Date: Fri, 26 Apr 2024 21:14:01 +0100 Subject: [PATCH] Add render pipeline builder --- src/lib.rs | 2 + src/pipeline.rs | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 src/pipeline.rs diff --git a/src/lib.rs b/src/lib.rs index 27bd34d..3097707 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,14 @@ mod bind_group; mod buffer; mod context; +mod pipeline; mod texture; pub use self::{ bind_group::{BindGroupBuilder, BindGroupLayoutBuilder}, buffer::{BufferExt, BulkBufferBuilder}, context::{Context, ContextBuilder}, + pipeline::RenderPipelineBuilder, texture::{Texture, TextureBuilder}, }; diff --git a/src/pipeline.rs b/src/pipeline.rs new file mode 100644 index 0000000..bba9446 --- /dev/null +++ b/src/pipeline.rs @@ -0,0 +1,108 @@ +use std::num::NonZeroU32; + +use crate::Context; + +pub struct RenderPipelineBuilder<'a> { + label: &'a str, + shader: &'a wgpu::ShaderModule, + layout_descriptor: Option>, + vertex: wgpu::VertexState<'a>, + fragment: Option>, + primitive: wgpu::PrimitiveState, + depth_stencil: Option, + multisample: wgpu::MultisampleState, + multiview: Option, +} + +impl<'a> RenderPipelineBuilder<'a> { + pub fn new(label: &'a str, shader: &'a wgpu::ShaderModule) -> Self { + Self { + label, + shader, + layout_descriptor: None, + vertex: wgpu::VertexState { + module: shader, + entry_point: "vertex", + buffers: &[], + }, + fragment: None, + primitive: wgpu::PrimitiveState::default(), + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), + multiview: None, + } + } + + pub fn with_layout( + mut self, + label: &'a str, + bind_group_layouts: &'a [&wgpu::BindGroupLayout], + push_constant_ranges: &'a [wgpu::PushConstantRange], + ) -> Self { + let layout_descriptor = wgpu::PipelineLayoutDescriptor { + label: Some(label), + bind_group_layouts, + push_constant_ranges, + }; + + self.layout_descriptor = Some(layout_descriptor); + self + } + + pub fn with_vertex_buffers(mut self, buffers: &'a [wgpu::VertexBufferLayout<'a>]) -> Self { + self.vertex.buffers = buffers; + self + } + + pub fn with_fragment_targets(mut self, targets: &'a [Option]) -> Self { + self.fragment = Some(wgpu::FragmentState { + module: self.shader, + entry_point: "fragment", + targets, + }); + self + } + + pub fn with_primitive(mut self, primitive: wgpu::PrimitiveState) -> Self { + self.primitive = primitive; + self + } + + pub fn with_depth_stencil(mut self, depth_stencil: wgpu::DepthStencilState) -> Self { + self.depth_stencil = Some(depth_stencil); + self + } + + pub fn with_multisample(mut self, multisample: wgpu::MultisampleState) -> Self { + self.multisample = multisample; + self + } + + pub fn with_multiview(mut self, multiview: NonZeroU32) -> Self { + self.multiview = Some(multiview); + self + } + + pub fn build(self, context: &Context) -> wgpu::RenderPipeline { + let raw_layout; + let layout = if let Some(descriptor) = self.layout_descriptor { + raw_layout = context.device.create_pipeline_layout(&descriptor); + Some(&raw_layout) + } else { + None + }; + + context + .device + .create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some(self.label), + layout, + vertex: self.vertex, + fragment: self.fragment, + primitive: self.primitive, + depth_stencil: self.depth_stencil, + multisample: self.multisample, + multiview: self.multiview, + }) + } +}