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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use scenix_core::ValidationError;
/// Render target backing used by a renderer instance.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum RenderTargetMode {
/// Frames are presented to a platform surface.
Surface,
/// Frames are rendered to an offscreen texture for tests, tools, or captures.
Headless,
}
/// Renderer initialization and resize configuration.
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct RendererConfig {
/// Render target width in pixels.
pub width: u32,
/// Render target height in pixels.
pub height: u32,
/// MSAA sample count. v0.6 supports `1` and `4`.
pub sample_count: u32,
/// Whether presentation should synchronize to display refresh.
pub vsync: bool,
/// Whether the renderer should use an HDR intermediate color target.
pub hdr: bool,
/// Surface present mode.
pub present_mode: wgpu::PresentMode,
/// Backends requested from wgpu.
pub backends: wgpu::Backends,
/// Clear color used before drawing.
pub clear_color: wgpu::Color,
}
impl RendererConfig {
/// Creates a renderer configuration for the supplied size.
#[inline]
pub fn new(width: u32, height: u32) -> Self {
Self {
width,
height,
..Self::default()
}
}
/// Validates render-target dimensions and MSAA count.
pub fn validate(&self) -> Result<(), ValidationError> {
if self.width == 0 || self.height == 0 {
return Err(ValidationError::OutOfRange);
}
if !matches!(self.sample_count, 1 | 4) {
return Err(ValidationError::OutOfRange);
}
if self.backends.is_empty() {
return Err(ValidationError::InvalidState);
}
Ok(())
}
/// Returns the preferred color format for this configuration.
#[inline]
pub const fn preferred_color_format(&self) -> wgpu::TextureFormat {
if self.hdr {
wgpu::TextureFormat::Rgba16Float
} else {
wgpu::TextureFormat::Bgra8UnormSrgb
}
}
/// Returns a copy with the dimensions changed.
#[inline]
pub fn resized(mut self, width: u32, height: u32) -> Self {
self.width = width;
self.height = height;
self
}
/// Returns a copy configured for vsync.
#[inline]
pub fn vsync(mut self, vsync: bool) -> Self {
self.vsync = vsync;
self.present_mode = if vsync {
wgpu::PresentMode::Fifo
} else {
wgpu::PresentMode::Immediate
};
self
}
/// Returns a copy configured for HDR intermediates.
#[inline]
pub const fn hdr(mut self, hdr: bool) -> Self {
self.hdr = hdr;
self
}
}
impl Default for RendererConfig {
#[inline]
fn default() -> Self {
Self {
width: 1280,
height: 720,
sample_count: 1,
vsync: true,
hdr: false,
present_mode: wgpu::PresentMode::Fifo,
backends: wgpu::Backends::all(),
clear_color: wgpu::Color {
r: 0.02,
g: 0.025,
b: 0.035,
a: 1.0,
},
}
}
}