use super::WGPUShader;
use wgpu;
pub struct RenderPipelineBuilder {
vertex_shader: Option<WGPUShader>,
fragment_shader: Option<WGPUShader>,
vertex_buffers: Vec<wgpu::VertexBufferLayout<'static>>,
targets: Vec<Option<wgpu::ColorTargetState>>,
primitive: wgpu::PrimitiveState,
depth_stencil: Option<wgpu::DepthStencilState>,
multisample: wgpu::MultisampleState,
}
impl RenderPipelineBuilder {
pub fn new() -> Self {
Self {
vertex_shader: None,
fragment_shader: None,
vertex_buffers: Vec::new(),
targets: vec![Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Bgra8UnormSrgb,
blend: Some(wgpu::BlendState::REPLACE),
write_mask: wgpu::ColorWrites::ALL,
})],
primitive: wgpu::PrimitiveState {
topology: wgpu::PrimitiveTopology::TriangleList,
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
polygon_mode: wgpu::PolygonMode::Fill,
unclipped_depth: false,
conservative: false,
},
depth_stencil: None,
multisample: wgpu::MultisampleState {
count: 1,
mask: !0,
alpha_to_coverage_enabled: false,
},
}
}
pub fn vertex_shader(mut self, shader: WGPUShader) -> Self {
self.vertex_shader = Some(shader);
self
}
pub fn fragment_shader(mut self, shader: WGPUShader) -> Self {
self.fragment_shader = Some(shader);
self
}
pub fn vertex_buffers(mut self, buffers: Vec<wgpu::VertexBufferLayout<'static>>) -> Self {
self.vertex_buffers = buffers;
self
}
pub fn color_target_format(mut self, format: wgpu::TextureFormat) -> Self {
self.targets = vec![Some(wgpu::ColorTargetState {
format,
blend: Some(wgpu::BlendState::REPLACE),
write_mask: wgpu::ColorWrites::ALL,
})];
self
}
pub fn primitive_topology(mut self, topology: wgpu::PrimitiveTopology) -> Self {
self.primitive.topology = topology;
self
}
pub fn depth_stencil(mut self, depth_stencil: wgpu::DepthStencilState) -> Self {
self.depth_stencil = Some(depth_stencil);
self
}
pub fn build(
self,
device: &wgpu::Device,
layout: &wgpu::PipelineLayout,
) -> Result<wgpu::RenderPipeline, String> {
let vertex_shader = self.vertex_shader
.ok_or("Vertex shader is required")?;
let fragment_shader = self.fragment_shader;
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("shdrlib render pipeline"),
layout: Some(layout),
vertex: wgpu::VertexState {
module: &vertex_shader.module,
entry_point: &vertex_shader.entry_point,
buffers: &self.vertex_buffers,
compilation_options: Default::default(),
},
fragment: fragment_shader.as_ref().map(|fs| wgpu::FragmentState {
module: &fs.module,
entry_point: &fs.entry_point,
targets: &self.targets,
compilation_options: Default::default(),
}),
primitive: self.primitive,
depth_stencil: self.depth_stencil,
multisample: self.multisample,
multiview: None,
cache: None,
});
Ok(pipeline)
}
}
impl Default for RenderPipelineBuilder {
fn default() -> Self {
Self::new()
}
}