Skip to content

Commit

Permalink
Enable multisampling by default in examples
Browse files Browse the repository at this point in the history
Closes #81.
  • Loading branch information
LPGhatguy committed Dec 6, 2023
1 parent 3f81109 commit 6427909
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 12 deletions.
13 changes: 12 additions & 1 deletion crates/bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,10 @@ async fn run(body: impl ExampleBody) {

window.set_ime_allowed(true);

let sample_count = get_sample_count();

// yakui_app has a helper for setting up winit and wgpu.
let mut app = yakui_app::Graphics::new(&window).await;
let mut app = yakui_app::Graphics::new(&window, sample_count).await;

// Create our yakui state. This is where our UI will be built, laid out, and
// calculations for painting will happen.
Expand Down Expand Up @@ -251,3 +253,12 @@ fn get_inset_override() -> Option<f32> {
.ok()
.and_then(|s| s.parse().ok())
}

/// Enables the user to override the number of multisampling samples that yakui
/// uses, defaulting to 4x MSAA.
fn get_sample_count() -> u32 {
std::env::var("YAKUI_SAMPLE_COUNT")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or(4)
}
2 changes: 1 addition & 1 deletion crates/demo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn app() {

async fn run(event_loop: EventLoop<()>, window: Window) {
let mut yak = Yakui::new();
let mut graphics = Graphics::new(&window).await;
let mut graphics = Graphics::new(&window, 4).await;

event_loop.set_control_flow(ControlFlow::Poll);
event_loop
Expand Down
29 changes: 19 additions & 10 deletions crates/yakui-app/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
mod multisampling;

use winit::{
dpi::PhysicalSize,
event::{Event, StartCause, WindowEvent},
event_loop::EventLoopWindowTarget,
window::Window,
};
use yakui_wgpu::SurfaceInfo;

use multisampling::Multisampling;

/// A helper for setting up rendering with winit and wgpu
pub struct Graphics {
Expand All @@ -15,6 +18,8 @@ pub struct Graphics {
surface: wgpu::Surface,
surface_config: wgpu::SurfaceConfiguration,
size: PhysicalSize<u32>,
sample_count: u32,
multisampling: Multisampling,

window: yakui_winit::YakuiWinit,
pub renderer: yakui_wgpu::YakuiWgpu,
Expand All @@ -24,7 +29,7 @@ pub struct Graphics {
}

impl Graphics {
pub async fn new(window: &Window) -> Self {
pub async fn new(window: &Window, sample_count: u32) -> Self {
let mut size = window.inner_size();

// FIXME: On web, we're receiving (0, 0) as the initial size of the
Expand Down Expand Up @@ -94,6 +99,8 @@ impl Graphics {
surface,
surface_config,
size,
sample_count,
multisampling: Multisampling::new(),

renderer,
window,
Expand Down Expand Up @@ -134,6 +141,14 @@ impl Graphics {
.texture
.create_view(&wgpu::TextureViewDescriptor::default());

let surface = self.multisampling.surface_info(
&self.device,
&view,
self.size,
self.format,
self.sample_count,
);

let mut encoder = self
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
Expand All @@ -144,8 +159,8 @@ impl Graphics {
let _render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Render Pass"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: &view,
resolve_target: None,
view: surface.color_attachment,
resolve_target: surface.resolve_target,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(bg),
store: wgpu::StoreOp::Store,
Expand All @@ -157,12 +172,6 @@ impl Graphics {

let clear = encoder.finish();

let surface = SurfaceInfo {
format: self.format,
sample_count: 1,
color_attachment: &view,
resolve_target: None,
};
let paint_yak = self.renderer.paint(yak, &self.device, &self.queue, surface);

self.queue.submit([clear, paint_yak]);
Expand Down
68 changes: 68 additions & 0 deletions crates/yakui-app/src/multisampling.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use winit::dpi::PhysicalSize;
use yakui_wgpu::SurfaceInfo;

pub(crate) struct Multisampling {
sample_count: u32,
format: wgpu::TextureFormat,
size: PhysicalSize<u32>,
ms_view: Option<wgpu::TextureView>,
}

impl Multisampling {
pub fn new() -> Self {
Self {
sample_count: 4,
format: wgpu::TextureFormat::Rgba8UnormSrgb,
size: PhysicalSize::new(800, 600),
ms_view: None,
}
}

pub fn surface_info<'a>(
&'a mut self,
device: &wgpu::Device,
view: &'a wgpu::TextureView,
size: PhysicalSize<u32>,
format: wgpu::TextureFormat,
sample_count: u32,
) -> SurfaceInfo<'a> {
if size != self.size || format != self.format || sample_count != self.sample_count {
self.ms_view = None;
}

if sample_count == 1 {
return SurfaceInfo {
format,
sample_count,
color_attachment: view,
resolve_target: None,
};
}

let ms_view = self.ms_view.get_or_insert_with(|| {
let texture = device.create_texture(&wgpu::TextureDescriptor {
label: Some("Multisampled Target"),
size: wgpu::Extent3d {
width: size.width,
height: size.height,
depth_or_array_layers: 1,
},
sample_count,
dimension: wgpu::TextureDimension::D2,
format,
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
mip_level_count: 1,
view_formats: &[],
});

texture.create_view(&Default::default())
});

SurfaceInfo {
format,
sample_count,
color_attachment: ms_view,
resolve_target: Some(view),
}
}
}

0 comments on commit 6427909

Please sign in to comment.