diff --git a/simulator/src/main.rs b/simulator/src/main.rs index 571e915..fd861ce 100644 --- a/simulator/src/main.rs +++ b/simulator/src/main.rs @@ -7,7 +7,7 @@ use cgmath::num_traits::{pow, ToPrimitive}; use cgmath::Rotation3; use pollster::FutureExt; use wgpu::util::DeviceExt; -use wgpu::{Adapter, Device, Instance, PresentMode, Queue, Surface, SurfaceCapabilities}; +use wgpu::{Adapter, Device, Instance, PresentMode, Queue, Surface, SurfaceCapabilities, SurfaceConfiguration}; use winit::application::ApplicationHandler; use winit::dpi::PhysicalSize; use winit::event::{ElementState, WindowEvent}; @@ -182,6 +182,7 @@ struct State<'a> { device: Device, queue: Queue, config: wgpu::SurfaceConfiguration, + // sample_count: u32, size: PhysicalSize, window: Arc, @@ -209,6 +210,9 @@ impl<'a> State<'a> { let surface_caps = surface.get_capabilities(&adapter); let config = Self::create_surface_config(size, surface_caps); surface.configure(&device, &config); + + let sample_count = Self::probe_msaa_support(&device, &config); + println!("Probe: {:?}", sample_count); let globals = Globals { aspect_ratio: config.width as f32 / config.height as f32, @@ -270,7 +274,7 @@ impl<'a> State<'a> { index_count: polygon_indices.len() as u32, }); - let (circle_vertices, circle_indices) = create_circle_vertices(32, 0.5, [0.5, 0.5, 0.5]); + let (circle_vertices, circle_indices) = create_circle_vertices(512, 0.5, [0.5, 0.5, 0.5]); let circle_vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: Some("Circle Vertex Buffer"), contents: bytemuck::cast_slice(&circle_vertices), @@ -335,7 +339,7 @@ impl<'a> State<'a> { let now = Instant::now(); let dt = now.duration_since(last).as_secs_f64(); last = now; - + { let mut sim = simulator_clone.write().unwrap(); let timewarp = sim.get_timewarp(); @@ -367,6 +371,34 @@ impl<'a> State<'a> { } } + fn probe_msaa_support(device: &wgpu::Device, config: &wgpu::SurfaceConfiguration) -> u32 { + for &count in &[16, 8, 4, 2] { + let texture_desc = wgpu::TextureDescriptor { + label: Some("MSAA Probe"), + size: wgpu::Extent3d { + width: 4, + height: 4, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: count, + dimension: wgpu::TextureDimension::D2, + format: config.format, + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + view_formats: &[], + }; + + // This will panic if not supported, so run this ONLY if you are confident (not ideal) + if let Ok(_) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + device.create_texture(&texture_desc); + })) { + return count; + } + } + + 1 // fallback + } + pub fn input(&mut self, event: &WindowEvent) -> bool { if let KeyboardInput { event, .. } = event { if event.state == ElementState::Pressed { @@ -467,7 +499,7 @@ impl<'a> State<'a> { }, depth_stencil: None, multisample: wgpu::MultisampleState { - count: 1, + count: 8, mask: !0, alpha_to_coverage_enabled: false, }, @@ -497,7 +529,7 @@ impl<'a> State<'a> { fn create_device(adapter: &Adapter) -> (Device, Queue) { adapter.request_device( &wgpu::DeviceDescriptor { - required_features: wgpu::Features::empty(), + required_features: wgpu::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES, required_limits: wgpu::Limits::default(), memory_hints: Default::default(), label: None, @@ -540,7 +572,22 @@ impl<'a> State<'a> { pub fn render(&mut self) -> Result<(), wgpu::SurfaceError> { let output = self.surface.get_current_texture()?; - let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default()); + + let multisampled_texture = self.device.create_texture(&wgpu::TextureDescriptor { + label: Some("Multisampled Render Target"), + size: wgpu::Extent3d { + width: self.config.width, + height: self.config.height, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 8, + dimension: wgpu::TextureDimension::D2, + format: self.config.format, + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + view_formats: &[], + }); + let multisampled_view = multisampled_texture.create_view(&Default::default()); let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some("Render Encoder"), @@ -550,8 +597,8 @@ impl<'a> State<'a> { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("Render Pass"), color_attachments: &[Some(wgpu::RenderPassColorAttachment { - view: &view, - resolve_target: None, + view: &multisampled_view, + resolve_target: Some(&output.texture.create_view(&Default::default())), ops: wgpu::Operations { load: wgpu::LoadOp::Clear(wgpu::Color { r: 1.0,