Add setting for the PresentMode

This commit is contained in:
Imbris 2021-02-06 16:21:39 -05:00 committed by Avi Weinstock
parent f307037a50
commit e2469152a3
4 changed files with 113 additions and 32 deletions

View File

@ -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",

View File

@ -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

View File

@ -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<PresentMode> 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,
}

View File

@ -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) => {