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
//! Anti-aliasing configuration.
use slotmap::SecondaryMap;
use crate::{bind_groups::BindGroupCreate, error::Result, AwsmRenderer};
/// Anti-aliasing configuration for the renderer.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct AntiAliasing {
// if None, no MSAA
// Some(4) is the only supported option for now
pub msaa_sample_count: Option<u32>,
pub smaa: bool,
pub mipmap: bool,
}
impl AntiAliasing {
/// Returns whether MSAA is enabled and supported.
pub fn has_msaa_checked(&self) -> crate::error::Result<bool> {
match self.msaa_sample_count {
Some(4) => Ok(true),
None => Ok(false),
Some(sample_count) => Err(crate::error::AwsmError::UnsupportedMsaaCount(sample_count)),
}
}
}
impl Default for AntiAliasing {
fn default() -> Self {
Self {
// Some(4) is the only supported option for now
msaa_sample_count: Some(4),
//msaa_sample_count: None,
smaa: false,
mipmap: true,
}
}
}
impl AwsmRenderer {
/// Updates the anti-aliasing settings and rebuilds dependent pipelines.
pub async fn set_anti_aliasing(&mut self, aa: AntiAliasing) -> Result<()> {
self.anti_aliasing = aa;
self.bind_groups
.mark_create(BindGroupCreate::AntiAliasingChange);
self.bind_groups
.mark_create(BindGroupCreate::TextureViewRecreate);
// OPAQUE: No pipeline updates needed here. All MSAA/mipmap variants are pre-created at init,
// and the correct one is selected at render time via get_compute_pipeline_key(&anti_aliasing).
//
// TRANSPARENT: Pipelines depend on per-mesh attributes AND anti-aliasing settings,
// so we must recreate them when anti-aliasing changes.
//
// DISPLAY: Pipelines depend on anti-aliasing settings, so we must recreate them when anti-aliasing changes.
let mut has_seen_buffer_info = SecondaryMap::new();
let mut has_seen_material = SecondaryMap::new();
for (key, mesh) in self.meshes.iter() {
let buffer_info_key = self.meshes.buffer_info_key(key)?;
if has_seen_buffer_info.insert(buffer_info_key, ()).is_none()
|| has_seen_material.insert(mesh.material_key, ()).is_none()
{
self.render_passes
.material_transparent
.pipelines
.set_render_pipeline_key(
&self.gpu,
mesh,
key,
buffer_info_key,
&mut self.shaders,
&mut self.pipelines,
&self.render_passes.material_transparent.bind_groups,
&self.pipeline_layouts,
&self.meshes.buffer_infos,
&self.anti_aliasing,
&self.textures,
&self.render_textures.formats,
)
.await?;
}
}
self.render_passes
.effects
.pipelines
.set_render_pipeline_keys(
&self.anti_aliasing,
&self.post_processing,
&self.gpu,
&mut self.shaders,
&mut self.pipelines,
&self.pipeline_layouts,
&self.render_textures.formats,
)
.await?;
Ok(())
}
}