pittore 0.2.4

Simple toolkit for 2D visualization based on wgpu.
Documentation
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,
        })
    }
}