use std::marker::PhantomData;
use crate::backend::RenderState;
use super::{bind_group::AsBindGroup, View};
pub struct PipelineSet {
pub pipeline: wgpu::RenderPipeline,
pub pipeline_bind_group: Box<dyn AsBindGroup>,
}
pub struct PipelineSpec<P: AsBindGroup, M: AsBindGroup> {
pub label: Option<&'static str>,
pub shader_id: u32,
pub fragment_color_target: Option<wgpu::ColorTargetState>,
pub primitive: wgpu::PrimitiveState,
pub marker: PhantomData<(P, M)>,
}
impl<P: AsBindGroup, M: AsBindGroup> Default for PipelineSpec<P, M> {
fn default() -> Self {
PipelineSpec {
label: None,
shader_id: 0,
fragment_color_target: None,
primitive: wgpu::PrimitiveState::default(),
marker: PhantomData,
}
}
}
impl<P: AsBindGroup, M: AsBindGroup> PipelineSpec<P, M> {
pub fn build(self, render_state: &RenderState) -> wgpu::RenderPipeline
where
P: Sized,
M: Sized,
{
let device = &render_state.device;
let shader = &render_state.shaders[self.shader_id];
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
bind_group_layouts: &[
&View::bind_group_layout(device),
&P::bind_group_layout(device),
&M::bind_group_layout(device),
],
..Default::default()
});
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("fill_pipeline"),
layout: Some(&pipeline_layout),
vertex: wgpu::VertexState {
module: shader,
entry_point: None,
buffers: &[],
compilation_options: wgpu::PipelineCompilationOptions::default(),
},
fragment: Some(wgpu::FragmentState {
module: shader,
entry_point: None,
compilation_options: wgpu::PipelineCompilationOptions::default(),
targets: &[self.fragment_color_target.or(Some(wgpu::ColorTargetState {
format: render_state.viewport.format,
blend: Some(wgpu::BlendState::ALPHA_BLENDING),
write_mask: wgpu::ColorWrites::ALL,
}))],
}),
primitive: self.primitive,
depth_stencil: None,
multisample: wgpu::MultisampleState {
count: 4,
..Default::default()
},
multiview: None,
cache: None,
})
}
}