1use std::ops::Deref;
2
3use crate::binding::{Binding, BindingGroup, BindingGroupLayout};
4use crate::buffers::UniformBuffer;
5use crate::device::Device;
6use crate::vertex::{VertexFormat, VertexLayout};
7
8#[derive(Debug)]
9pub struct Pipeline {
10 pub wgpu: wgpu::RenderPipeline,
11
12 pub layout: PipelineLayout,
13 pub vertex_layout: VertexLayout,
14}
15
16#[derive(Clone, Debug, PartialEq, Eq)]
17pub struct Blending {
18 src_factor: BlendFactor,
19 dst_factor: BlendFactor,
20 operation: BlendOp,
21}
22
23impl Blending {
24 pub fn new(src_factor: BlendFactor, dst_factor: BlendFactor, operation: BlendOp) -> Self {
25 Blending {
26 src_factor,
27 dst_factor,
28 operation,
29 }
30 }
31
32 pub fn constant() -> Self {
33 Blending {
34 src_factor: BlendFactor::One,
35 dst_factor: BlendFactor::Zero,
36 operation: BlendOp::Add,
37 }
38 }
39
40 pub fn as_wgpu(&self) -> (wgpu::BlendFactor, wgpu::BlendFactor, wgpu::BlendOperation) {
41 (
42 self.src_factor.as_wgpu(),
43 self.dst_factor.as_wgpu(),
44 self.operation.as_wgpu(),
45 )
46 }
47}
48
49impl Default for Blending {
50 fn default() -> Self {
51 Blending {
52 src_factor: BlendFactor::SrcAlpha,
53 dst_factor: BlendFactor::OneMinusSrcAlpha,
54 operation: BlendOp::Add,
55 }
56 }
57}
58
59#[derive(Copy, Clone, Debug, PartialEq, Eq)]
60pub enum BlendFactor {
61 One,
62 Zero,
63 SrcAlpha,
64 OneMinusSrcAlpha,
65}
66
67impl BlendFactor {
68 fn as_wgpu(&self) -> wgpu::BlendFactor {
69 match self {
70 BlendFactor::SrcAlpha => wgpu::BlendFactor::SrcAlpha,
71 BlendFactor::OneMinusSrcAlpha => wgpu::BlendFactor::OneMinusSrcAlpha,
72 BlendFactor::One => wgpu::BlendFactor::One,
73 BlendFactor::Zero => wgpu::BlendFactor::Zero,
74 }
75 }
76}
77
78#[derive(Copy, Clone, Debug, PartialEq, Eq)]
79pub enum BlendOp {
80 Add,
81}
82
83impl BlendOp {
84 fn as_wgpu(&self) -> wgpu::BlendOperation {
85 match self {
86 BlendOp::Add => wgpu::BlendOperation::Add,
87 }
88 }
89}
90
91#[derive(Debug)]
92pub struct Set<'a>(pub &'a [Binding]);
93
94#[derive(Debug)]
95pub struct PipelineLayout {
96 pub sets: Vec<BindingGroupLayout>,
97}
98
99pub struct PipelineCore {
100 pub pipeline: Pipeline,
101 pub bindings: BindingGroup,
102 pub uniforms: UniformBuffer,
103}
104
105pub trait AbstractPipeline<'a>: Deref<Target = PipelineCore> {
106 type PrepareContext;
107 type Uniforms: bytemuck::Pod + Copy + 'static;
108
109 fn description() -> PipelineDescription<'a>;
110 fn setup(pip: Pipeline, dev: &Device) -> Self;
111 fn prepare(
112 &'a self,
113 context: Self::PrepareContext,
114 ) -> Option<(&'a UniformBuffer, Vec<Self::Uniforms>)>;
115}
116
117#[derive(Debug)]
118pub struct PipelineDescription<'a> {
119 pub vertex_layout: &'a [VertexFormat],
120 pub pipeline_layout: &'a [Set<'a>],
121 pub vertex_shader: &'static [u8],
122 pub fragment_shader: &'static [u8],
123}