From 85fa038796df1692479ce7052a06c35d2979ac44 Mon Sep 17 00:00:00 2001 From: Imbris Date: Sat, 6 Feb 2021 16:21:39 -0500 Subject: [PATCH] Add setting for the PresentMode --- assets/voxygen/i18n/en/hud/hud_settings.ron | 4 + voxygen/src/hud/settings_window/video.rs | 107 ++++++++++++++------ voxygen/src/render/mod.rs | 25 +++++ voxygen/src/render/renderer.rs | 9 +- 4 files changed, 113 insertions(+), 32 deletions(-) diff --git a/assets/voxygen/i18n/en/hud/hud_settings.ron b/assets/voxygen/i18n/en/hud/hud_settings.ron index 7706b81b24..bfdb78979a 100644 --- a/assets/voxygen/i18n/en/hud/hud_settings.ron +++ b/assets/voxygen/i18n/en/hud/hud_settings.ron @@ -57,6 +57,10 @@ "hud.settings.sprites_view_distance": "Sprites View Distance", "hud.settings.figures_view_distance": "Entities View Distance", "hud.settings.maximum_fps": "Maximum FPS", + "hud.settings.present_mode": "Present Mode", + "hud.settings.present_mode.fifo": "Fifo", + "hud.settings.present_mode.mailbox": "Mailbox", + "hud.settings.present_mode.immediate": "Immediate", "hud.settings.fov": "Field of View (deg)", "hud.settings.gamma": "Gamma", "hud.settings.exposure": "Exposure", diff --git a/voxygen/src/hud/settings_window/video.rs b/voxygen/src/hud/settings_window/video.rs index 9f697d9c66..0f52031823 100644 --- a/voxygen/src/hud/settings_window/video.rs +++ b/voxygen/src/hud/settings_window/video.rs @@ -7,10 +7,10 @@ use crate::{ }, i18n::Localization, render::{ - AaMode, CloudMode, FluidMode, LightingMode, RenderMode, ShadowMapMode, ShadowMode, - UpscaleMode, + AaMode, CloudMode, FluidMode, LightingMode, PresentMode, RenderMode, ShadowMapMode, + ShadowMode, UpscaleMode, }, - session::settings_change::{Graphics as GraphicsChange, Graphics::*}, + session::settings_change::Graphics as GraphicsChange, settings::Fps, ui::{fonts::Fonts, ImageSlider, ToggleButton}, window::{FullScreenSettings, FullscreenMode}, @@ -50,6 +50,8 @@ widget_ids! { max_fps_slider, max_fps_text, max_fps_value, + present_mode_text, + present_mode_list, fov_slider, fov_text, fov_value, @@ -227,7 +229,7 @@ impl<'a> Widget for Video<'a> { .pad_track((5.0, 5.0)) .set(state.ids.vd_slider, ui) { - events.push(AdjustViewDistance(new_val)); + events.push(GraphicsChange::AdjustViewDistance(new_val)); } Text::new(&format!( @@ -265,7 +267,7 @@ impl<'a> Widget for Video<'a> { .pad_track((5.0, 5.0)) .set(state.ids.max_fps_slider, ui) { - events.push(ChangeMaxFPS(FPS_CHOICES[which])); + events.push(GraphicsChange::ChangeMaxFPS(FPS_CHOICES[which])); } Text::new(&self.global_state.settings.graphics.max_fps.to_string()) @@ -275,6 +277,53 @@ impl<'a> Widget for Video<'a> { .color(TEXT_COLOR) .set(state.ids.max_fps_value, ui); + // Get render mode + let render_mode = &self.global_state.settings.graphics.render_mode; + + // Present Mode + Text::new(&self.localized_strings.get("hud.settings.present_mode")) + .down_from(state.ids.vd_slider, 10.0) + .right_from(state.ids.max_fps_value, 30.0) + .font_size(self.fonts.cyri.scale(14)) + .font_id(self.fonts.cyri.conrod_id) + .color(TEXT_COLOR) + .set(state.ids.present_mode_text, ui); + + let mode_list = [ + PresentMode::Fifo, + PresentMode::Mailbox, + PresentMode::Immediate, + ]; + let mode_label_list = [ + &self.localized_strings.get("hud.settings.present_mode.fifo"), + &self + .localized_strings + .get("hud.settings.present_mode.mailbox"), + &self + .localized_strings + .get("hud.settings.present_mode.immediate"), + ]; + + // Get which present mode is currently active + let selected = mode_list + .iter() + .position(|x| *x == render_mode.present_mode); + + if let Some(clicked) = DropDownList::new(&mode_label_list, selected) + .w_h(120.0, 22.0) + .color(MENU_BG) + .label_color(TEXT_COLOR) + .label_font_id(self.fonts.cyri.conrod_id) + .down_from(state.ids.present_mode_text, 8.0) + .align_middle_x() + .set(state.ids.present_mode_list, ui) + { + events.push(GraphicsChange::ChangeRenderMode(Box::new(RenderMode { + present_mode: mode_list[clicked], + ..render_mode.clone() + }))); + } + // FOV Text::new(&self.localized_strings.get("hud.settings.fov")) .down_from(state.ids.max_fps_slider, 10.0) @@ -297,7 +346,7 @@ impl<'a> Widget for Video<'a> { .pad_track((5.0, 5.0)) .set(state.ids.fov_slider, ui) { - events.push(ChangeFOV(new_val)); + events.push(GraphicsChange::ChangeFOV(new_val)); } Text::new(&format!("{}", self.global_state.settings.graphics.fov)) @@ -330,7 +379,7 @@ impl<'a> Widget for Video<'a> { .pad_track((5.0, 5.0)) .set(state.ids.lod_detail_slider, ui) { - events.push(AdjustLodDetail( + events.push(GraphicsChange::AdjustLodDetail( (5.0f32.powf(new_val as f32 / 10.0) * 100.0) as u32, )); } @@ -367,7 +416,9 @@ impl<'a> Widget for Video<'a> { .pad_track((5.0, 5.0)) .set(state.ids.gamma_slider, ui) { - events.push(ChangeGamma(2.0f32.powf(new_val as f32 / 8.0))); + events.push(GraphicsChange::ChangeGamma( + 2.0f32.powf(new_val as f32 / 8.0), + )); } Text::new(&format!("{:.2}", self.global_state.settings.graphics.gamma)) @@ -392,7 +443,7 @@ impl<'a> Widget for Video<'a> { .pad_track((5.0, 5.0)) .set(state.ids.exposure_slider, ui) { - events.push(ChangeExposure(new_val as f32 / 16.0)); + events.push(GraphicsChange::ChangeExposure(new_val as f32 / 16.0)); } Text::new(&self.localized_strings.get("hud.settings.exposure")) @@ -430,7 +481,7 @@ impl<'a> Widget for Video<'a> { .pad_track((5.0, 5.0)) .set(state.ids.ambiance_slider, ui) { - events.push(ChangeAmbiance(new_val as f32)); + events.push(GraphicsChange::ChangeAmbiance(new_val as f32)); } Text::new(&self.localized_strings.get("hud.settings.ambiance")) .up_from(state.ids.ambiance_slider, 8.0) @@ -466,7 +517,7 @@ impl<'a> Widget for Video<'a> { .pad_track((5.0, 5.0)) .set(state.ids.sprite_dist_slider, ui) { - events.push(AdjustSpriteRenderDistance(new_val)); + events.push(GraphicsChange::AdjustSpriteRenderDistance(new_val)); } Text::new( &self @@ -506,7 +557,7 @@ impl<'a> Widget for Video<'a> { .pad_track((5.0, 5.0)) .set(state.ids.figure_dist_slider, ui) { - events.push(AdjustFigureLoDRenderDistance(new_val)); + events.push(GraphicsChange::AdjustFigureLoDRenderDistance(new_val)); } Text::new( &self @@ -532,8 +583,6 @@ impl<'a> Widget for Video<'a> { .color(TEXT_COLOR) .set(state.ids.figure_dist_value, ui); - let render_mode = &self.global_state.settings.graphics.render_mode; - // AaMode Text::new(&self.localized_strings.get("hud.settings.antialiasing_mode")) .down_from(state.ids.gamma_slider, 8.0) @@ -570,7 +619,7 @@ impl<'a> Widget for Video<'a> { .down_from(state.ids.aa_mode_text, 8.0) .set(state.ids.aa_mode_list, ui) { - events.push(ChangeRenderMode(Box::new(RenderMode { + events.push(GraphicsChange::ChangeRenderMode(Box::new(RenderMode { aa: mode_list[clicked], ..render_mode.clone() }))); @@ -610,7 +659,7 @@ impl<'a> Widget for Video<'a> { .down_from(state.ids.upscale_factor_text, 8.0) .set(state.ids.upscale_factor_list, ui) { - events.push(ChangeRenderMode(Box::new(RenderMode { + events.push(GraphicsChange::ChangeRenderMode(Box::new(RenderMode { upscale_mode: UpscaleMode { factor: upscale_factors[clicked], }, @@ -668,7 +717,7 @@ impl<'a> Widget for Video<'a> { .down_from(state.ids.cloud_mode_text, 8.0) .set(state.ids.cloud_mode_list, ui) { - events.push(ChangeRenderMode(Box::new(RenderMode { + events.push(GraphicsChange::ChangeRenderMode(Box::new(RenderMode { cloud: mode_list[clicked], ..render_mode.clone() }))); @@ -707,7 +756,7 @@ impl<'a> Widget for Video<'a> { .down_from(state.ids.fluid_mode_text, 8.0) .set(state.ids.fluid_mode_list, ui) { - events.push(ChangeRenderMode(Box::new(RenderMode { + events.push(GraphicsChange::ChangeRenderMode(Box::new(RenderMode { fluid: mode_list[clicked], ..render_mode.clone() }))); @@ -753,7 +802,7 @@ impl<'a> Widget for Video<'a> { .down_from(state.ids.lighting_mode_text, 8.0) .set(state.ids.lighting_mode_list, ui) { - events.push(ChangeRenderMode(Box::new(RenderMode { + events.push(GraphicsChange::ChangeRenderMode(Box::new(RenderMode { lighting: mode_list[clicked], ..render_mode.clone() }))); @@ -800,7 +849,7 @@ impl<'a> Widget for Video<'a> { .down_from(state.ids.shadow_mode_text, 8.0) .set(state.ids.shadow_mode_list, ui) { - events.push(ChangeRenderMode(Box::new(RenderMode { + events.push(GraphicsChange::ChangeRenderMode(Box::new(RenderMode { shadow: mode_list[clicked], ..render_mode.clone() }))); @@ -833,7 +882,7 @@ impl<'a> Widget for Video<'a> { .pad_track((5.0, 5.0)) .set(state.ids.shadow_mode_map_resolution_slider, ui) { - events.push(ChangeRenderMode(Box::new(RenderMode { + events.push(GraphicsChange::ChangeRenderMode(Box::new(RenderMode { shadow: ShadowMode::Map(ShadowMapMode { resolution: 2.0f32.powf(f32::from(new_val) / 4.0), }), @@ -871,7 +920,7 @@ impl<'a> Widget for Video<'a> { .set(state.ids.particles_button, ui); if self.global_state.settings.graphics.particles_enabled != particles_enabled { - events.push(ToggleParticlesEnabled(particles_enabled)); + events.push(GraphicsChange::ToggleParticlesEnabled(particles_enabled)); } // Resolution @@ -908,7 +957,7 @@ impl<'a> Widget for Video<'a> { .down_from(state.ids.resolution_label, 10.0) .set(state.ids.resolution, ui) { - events.push(ChangeFullscreenMode(FullScreenSettings { + events.push(GraphicsChange::ChangeFullscreenMode(FullScreenSettings { resolution: resolutions[clicked], ..self.global_state.settings.graphics.fullscreen })); @@ -972,7 +1021,7 @@ impl<'a> Widget for Video<'a> { .right_from(state.ids.resolution, 8.0) .set(state.ids.bit_depth, ui) { - events.push(ChangeFullscreenMode(FullScreenSettings { + events.push(GraphicsChange::ChangeFullscreenMode(FullScreenSettings { bit_depth: if clicked == 0 { None } else { @@ -1026,7 +1075,7 @@ impl<'a> Widget for Video<'a> { .right_from(state.ids.bit_depth, 8.0) .set(state.ids.refresh_rate, ui) { - events.push(ChangeFullscreenMode(FullScreenSettings { + events.push(GraphicsChange::ChangeFullscreenMode(FullScreenSettings { refresh_rate: if clicked == 0 { None } else { @@ -1056,7 +1105,7 @@ impl<'a> Widget for Video<'a> { .set(state.ids.fullscreen_button, ui); if self.global_state.settings.graphics.fullscreen.enabled != enabled { - events.push(ChangeFullscreenMode(FullScreenSettings { + events.push(GraphicsChange::ChangeFullscreenMode(FullScreenSettings { enabled, ..self.global_state.settings.graphics.fullscreen })); @@ -1093,7 +1142,7 @@ impl<'a> Widget for Video<'a> { .down_from(state.ids.fullscreen_mode_text, 8.0) .set(state.ids.fullscreen_mode_list, ui) { - events.push(ChangeFullscreenMode(FullScreenSettings { + events.push(GraphicsChange::ChangeFullscreenMode(FullScreenSettings { mode: mode_list[clicked], ..self.global_state.settings.graphics.fullscreen })); @@ -1113,7 +1162,7 @@ impl<'a> Widget for Video<'a> { .set(state.ids.save_window_size_button, ui) .was_clicked() { - events.push(AdjustWindowSize( + events.push(GraphicsChange::AdjustWindowSize( self.global_state .window .logical_size() @@ -1137,7 +1186,7 @@ impl<'a> Widget for Video<'a> { .set(state.ids.reset_graphics_button, ui) .was_clicked() { - events.push(ResetGraphicsSettings); + events.push(GraphicsChange::ResetGraphicsSettings); } events diff --git a/voxygen/src/render/mod.rs b/voxygen/src/render/mod.rs index 4bd6c41860..358fd90e50 100644 --- a/voxygen/src/render/mod.rs +++ b/voxygen/src/render/mod.rs @@ -235,6 +235,30 @@ impl Default for UpscaleMode { fn default() -> Self { Self { factor: 1.0 } } } +/// Present modes +/// See https://docs.rs/wgpu/0.7.0/wgpu/enum.PresentMode.html +#[derive(PartialEq, Clone, Copy, Debug, Serialize, Deserialize)] +pub enum PresentMode { + Fifo, + Mailbox, + #[serde(other)] + Immediate, +} + +impl Default for PresentMode { + fn default() -> Self { Self::Immediate } +} + +impl From for wgpu::PresentMode { + fn from(mode: PresentMode) -> Self { + match mode { + PresentMode::Fifo => wgpu::PresentMode::Fifo, + PresentMode::Mailbox => wgpu::PresentMode::Mailbox, + PresentMode::Immediate => wgpu::PresentMode::Immediate, + } + } +} + /// Render modes #[derive(PartialEq, Clone, Debug, Default, Serialize, Deserialize)] #[serde(default)] @@ -245,4 +269,5 @@ pub struct RenderMode { pub lighting: LightingMode, pub shadow: ShadowMode, pub upscale_mode: UpscaleMode, + pub present_mode: PresentMode, } diff --git a/voxygen/src/render/renderer.rs b/voxygen/src/render/renderer.rs index b55d24ac38..e37e6f15ef 100644 --- a/voxygen/src/render/renderer.rs +++ b/voxygen/src/render/renderer.rs @@ -351,7 +351,7 @@ impl Renderer { format: wgpu::TextureFormat::Bgra8UnormSrgb, width: dims.width, height: dims.height, - present_mode: wgpu::PresentMode::Immediate, + present_mode: mode.present_mode.into(), }; let swap_chain = device.create_swap_chain(&surface, &sc_desc); @@ -563,6 +563,7 @@ impl Renderer { /// Change the render mode. pub fn set_render_mode(&mut self, mode: RenderMode) -> Result<(), RenderError> { self.mode = mode; + self.sc_desc.present_mode = self.mode.present_mode.into(); // Recreate render target self.on_resize(self.resolution)?; @@ -1033,8 +1034,10 @@ impl Renderer { warn!("{}. Recreating swap chain. A frame will be missed", err); return self.on_resize(self.resolution).map(|()| None); }, - Err(err @ wgpu::SwapChainError::Timeout) => { - warn!("{}. This will probably be resolved on the next frame", err); + Err(wgpu::SwapChainError::Timeout) => { + // This will probably be resolved on the next frame + // NOTE: we don't log this because it happens very frequently with + // PresentMode::Fifo and unlimited FPS return Ok(None); }, Err(err @ wgpu::SwapChainError::Outdated) => {