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