1use std::marker::PhantomData;
2use std::ops::Deref;
3
4use bytemuck::{Pod, Zeroable};
5use easygpu::prelude::*;
6use easygpu::wgpu::TextureFormat;
7
8pub struct LyonPipeline<T> {
10 pipeline: PipelineCore,
11 _phantom: PhantomData<T>,
12}
13
14#[repr(C)]
15#[derive(Copy, Clone, Pod, Zeroable)]
16pub struct Uniforms {
18 pub ortho: [f32; 16],
20 pub transform: [f32; 16],
22}
23
24pub trait VertexShaderSource {
25 fn shader() -> &'static [u8];
26
27 fn sampler_format() -> TextureFormat;
28}
29
30pub struct Srgb;
31pub struct Normal;
32
33impl VertexShaderSource for Srgb {
34 fn shader() -> &'static [u8] {
35 include_bytes!("shaders/shape-srgb.vert.spv")
36 }
37
38 fn sampler_format() -> TextureFormat {
39 TextureFormat::Bgra8UnormSrgb
40 }
41}
42
43impl VertexShaderSource for Normal {
44 fn shader() -> &'static [u8] {
45 include_bytes!("shaders/shape.vert.spv")
46 }
47
48 fn sampler_format() -> TextureFormat {
49 TextureFormat::Bgra8Unorm
50 }
51}
52
53impl<'a, T> AbstractPipeline<'a> for LyonPipeline<T>
54where
55 T: VertexShaderSource,
56{
57 type PrepareContext = ScreenTransformation<f32>;
58 type Uniforms = Uniforms;
59
60 fn description() -> PipelineDescription<'a> {
61 PipelineDescription {
62 vertex_layout: &[VertexFormat::Float3, VertexFormat::UByte4],
63 pipeline_layout: &[Set(&[Binding {
64 binding: BindingType::UniformBuffer,
65 stage: ShaderStages::VERTEX,
66 }])],
67 vertex_shader: T::shader(),
68 fragment_shader: include_bytes!("shaders/shape.frag.spv"),
69 }
70 }
71
72 fn setup(pipeline: Pipeline, dev: &Device) -> Self {
73 let transform = ScreenTransformation::identity().to_array();
74 let ortho = ScreenTransformation::identity().to_array();
75 let uniforms = dev.create_uniform_buffer(&[self::Uniforms { ortho, transform }]);
76 let bindings = dev.create_binding_group(&pipeline.layout.sets[0], &[&uniforms]);
77
78 Self {
79 pipeline: PipelineCore {
80 pipeline,
81 uniforms,
82 bindings,
83 },
84 _phantom: PhantomData::default(),
85 }
86 }
87
88 fn prepare(
89 &'a self,
90 ortho: Self::PrepareContext,
91 ) -> Option<(&'a UniformBuffer, Vec<Self::Uniforms>)> {
92 let ortho = ortho.to_array();
93 let transform = ScreenTransformation::identity().to_array();
94 Some((
95 &self.pipeline.uniforms,
96 vec![self::Uniforms { transform, ortho }],
97 ))
98 }
99}
100
101impl<T> Deref for LyonPipeline<T> {
102 type Target = PipelineCore;
103
104 fn deref(&self) -> &Self::Target {
105 &self.pipeline
106 }
107}