Implemented Multi Sampling - TODO: Check fot adapter capabilities

This commit is contained in:
Verox001 2025-05-05 01:25:23 +02:00
parent de8dca3536
commit aad4355b30

View File

@ -7,7 +7,7 @@ use cgmath::num_traits::{pow, ToPrimitive};
use cgmath::Rotation3; use cgmath::Rotation3;
use pollster::FutureExt; use pollster::FutureExt;
use wgpu::util::DeviceExt; 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::application::ApplicationHandler;
use winit::dpi::PhysicalSize; use winit::dpi::PhysicalSize;
use winit::event::{ElementState, WindowEvent}; use winit::event::{ElementState, WindowEvent};
@ -182,6 +182,7 @@ struct State<'a> {
device: Device, device: Device,
queue: Queue, queue: Queue,
config: wgpu::SurfaceConfiguration, config: wgpu::SurfaceConfiguration,
// sample_count: u32,
size: PhysicalSize<u32>, size: PhysicalSize<u32>,
window: Arc<Window>, window: Arc<Window>,
@ -209,6 +210,9 @@ impl<'a> State<'a> {
let surface_caps = surface.get_capabilities(&adapter); let surface_caps = surface.get_capabilities(&adapter);
let config = Self::create_surface_config(size, surface_caps); let config = Self::create_surface_config(size, surface_caps);
surface.configure(&device, &config); surface.configure(&device, &config);
let sample_count = Self::probe_msaa_support(&device, &config);
println!("Probe: {:?}", sample_count);
let globals = Globals { let globals = Globals {
aspect_ratio: config.width as f32 / config.height as f32, 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, 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 { let circle_vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Circle Vertex Buffer"), label: Some("Circle Vertex Buffer"),
contents: bytemuck::cast_slice(&circle_vertices), contents: bytemuck::cast_slice(&circle_vertices),
@ -335,7 +339,7 @@ impl<'a> State<'a> {
let now = Instant::now(); let now = Instant::now();
let dt = now.duration_since(last).as_secs_f64(); let dt = now.duration_since(last).as_secs_f64();
last = now; last = now;
{ {
let mut sim = simulator_clone.write().unwrap(); let mut sim = simulator_clone.write().unwrap();
let timewarp = sim.get_timewarp(); 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 { pub fn input(&mut self, event: &WindowEvent) -> bool {
if let KeyboardInput { event, .. } = event { if let KeyboardInput { event, .. } = event {
if event.state == ElementState::Pressed { if event.state == ElementState::Pressed {
@ -467,7 +499,7 @@ impl<'a> State<'a> {
}, },
depth_stencil: None, depth_stencil: None,
multisample: wgpu::MultisampleState { multisample: wgpu::MultisampleState {
count: 1, count: 8,
mask: !0, mask: !0,
alpha_to_coverage_enabled: false, alpha_to_coverage_enabled: false,
}, },
@ -497,7 +529,7 @@ impl<'a> State<'a> {
fn create_device(adapter: &Adapter) -> (Device, Queue) { fn create_device(adapter: &Adapter) -> (Device, Queue) {
adapter.request_device( adapter.request_device(
&wgpu::DeviceDescriptor { &wgpu::DeviceDescriptor {
required_features: wgpu::Features::empty(), required_features: wgpu::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
required_limits: wgpu::Limits::default(), required_limits: wgpu::Limits::default(),
memory_hints: Default::default(), memory_hints: Default::default(),
label: None, label: None,
@ -540,7 +572,22 @@ impl<'a> State<'a> {
pub fn render(&mut self) -> Result<(), wgpu::SurfaceError> { pub fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
let output = self.surface.get_current_texture()?; 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 { let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Render Encoder"), label: Some("Render Encoder"),
@ -550,8 +597,8 @@ impl<'a> State<'a> {
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Render Pass"), label: Some("Render Pass"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment { color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: &view, view: &multisampled_view,
resolve_target: None, resolve_target: Some(&output.texture.create_view(&Default::default())),
ops: wgpu::Operations { ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color { load: wgpu::LoadOp::Clear(wgpu::Color {
r: 1.0, r: 1.0,