From e1af485e5f70c2cac794dd2282644c3c4810db9a 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 037e4868d1..e21aefa9dc 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 835bb1eb69..d41b239d8b 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, @@ -229,7 +231,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!( @@ -267,7 +269,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()) @@ -277,6 +279,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) @@ -299,7 +348,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)) @@ -332,7 +381,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, )); } @@ -369,7 +418,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)) @@ -394,7 +445,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")) @@ -432,7 +483,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) @@ -468,7 +519,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 @@ -508,7 +559,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 @@ -534,8 +585,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) @@ -572,7 +621,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() }))); @@ -612,7 +661,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], }, @@ -670,7 +719,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() }))); @@ -709,7 +758,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() }))); @@ -755,7 +804,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() }))); @@ -802,7 +851,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() }))); @@ -835,7 +884,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), }), @@ -873,7 +922,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)); } // Lossy terrain compression @@ -946,7 +995,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 })); @@ -1010,7 +1059,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 { @@ -1064,7 +1113,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 { @@ -1094,7 +1143,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 })); @@ -1131,7 +1180,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 })); @@ -1151,7 +1200,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() @@ -1175,7 +1224,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) => {