mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Display gpu timing info in the HUD when enabled
This commit is contained in:
parent
f736c180b8
commit
f2d97345e5
@ -229,6 +229,7 @@ widget_ids! {
|
|||||||
num_lights,
|
num_lights,
|
||||||
num_figures,
|
num_figures,
|
||||||
num_particles,
|
num_particles,
|
||||||
|
gpu_timings[],
|
||||||
|
|
||||||
// Game Version
|
// Game Version
|
||||||
version,
|
version,
|
||||||
@ -2048,6 +2049,33 @@ impl Hud {
|
|||||||
.font_size(self.fonts.cyri.scale(14))
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
.set(self.ids.num_particles, ui_widgets);
|
.set(self.ids.num_particles, ui_widgets);
|
||||||
|
|
||||||
|
// GPU timing for different pipelines
|
||||||
|
let gpu_timings = global_state.window.renderer().timings();
|
||||||
|
if !gpu_timings.is_empty() {
|
||||||
|
let num_timings = gpu_timings.len();
|
||||||
|
// Make sure we have enoung ids
|
||||||
|
if self.ids.gpu_timings.len() < num_timings {
|
||||||
|
self.ids
|
||||||
|
.gpu_timings
|
||||||
|
.resize(num_timings, &mut ui_widgets.widget_id_generator());
|
||||||
|
}
|
||||||
|
for (i, timing) in gpu_timings.iter().enumerate() {
|
||||||
|
Text::new(&format!(
|
||||||
|
"{:16}{:.3} ms",
|
||||||
|
&format!("{}:", timing.1),
|
||||||
|
timing.2 * 1000.0,
|
||||||
|
))
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.down(5.0)
|
||||||
|
.x_place_on(
|
||||||
|
ui_widgets.window,
|
||||||
|
conrod_core::position::Place::Start(Some(5.0 + 10.0 * timing.0 as f64)),
|
||||||
|
)
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
|
.set(self.ids.gpu_timings[i], ui_widgets);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Help Window
|
// Help Window
|
||||||
if let Some(help_key) = global_state.settings.controls.get_binding(GameInput::Help) {
|
if let Some(help_key) = global_state.settings.controls.get_binding(GameInput::Help) {
|
||||||
Text::new(
|
Text::new(
|
||||||
@ -2056,7 +2084,7 @@ impl Hud {
|
|||||||
.replace("{key}", help_key.display_string(key_layout).as_str()),
|
.replace("{key}", help_key.display_string(key_layout).as_str()),
|
||||||
)
|
)
|
||||||
.color(TEXT_COLOR)
|
.color(TEXT_COLOR)
|
||||||
.down_from(self.ids.num_particles, 5.0)
|
.down(5.0)
|
||||||
.font_id(self.fonts.cyri.conrod_id)
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
.font_size(self.fonts.cyri.scale(14))
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
.set(self.ids.help_info, ui_widgets);
|
.set(self.ids.help_info, ui_widgets);
|
||||||
|
@ -118,6 +118,7 @@ pub struct Renderer {
|
|||||||
resolution: Vec2<u32>,
|
resolution: Vec2<u32>,
|
||||||
|
|
||||||
profiler: wgpu_profiler::GpuProfiler,
|
profiler: wgpu_profiler::GpuProfiler,
|
||||||
|
profile_times: Vec<wgpu_profiler::GpuTimerScopeResult>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer {
|
impl Renderer {
|
||||||
@ -341,7 +342,7 @@ impl Renderer {
|
|||||||
create_quad_index_buffer_u16(&device, QUAD_INDEX_BUFFER_U16_START_VERT_LEN as usize);
|
create_quad_index_buffer_u16(&device, QUAD_INDEX_BUFFER_U16_START_VERT_LEN as usize);
|
||||||
let quad_index_buffer_u32 =
|
let quad_index_buffer_u32 =
|
||||||
create_quad_index_buffer_u32(&device, QUAD_INDEX_BUFFER_U32_START_VERT_LEN as usize);
|
create_quad_index_buffer_u32(&device, QUAD_INDEX_BUFFER_U32_START_VERT_LEN as usize);
|
||||||
let mut profiler = wgpu_profiler::GpuProfiler::new(1, queue.get_timestamp_period());
|
let mut profiler = wgpu_profiler::GpuProfiler::new(4, queue.get_timestamp_period());
|
||||||
profiler.enable_timer = mode.profiler_enabled;
|
profiler.enable_timer = mode.profiler_enabled;
|
||||||
profiler.enable_debug_marker = mode.profiler_enabled;
|
profiler.enable_debug_marker = mode.profiler_enabled;
|
||||||
|
|
||||||
@ -371,6 +372,7 @@ impl Renderer {
|
|||||||
resolution: Vec2::new(dims.width, dims.height),
|
resolution: Vec2::new(dims.width, dims.height),
|
||||||
|
|
||||||
profiler,
|
profiler,
|
||||||
|
profile_times: Vec::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -380,6 +382,10 @@ impl Renderer {
|
|||||||
self.sc_desc.present_mode = self.mode.present_mode.into();
|
self.sc_desc.present_mode = self.mode.present_mode.into();
|
||||||
|
|
||||||
// Enable/disable profiler
|
// Enable/disable profiler
|
||||||
|
if !self.mode.profiler_enabled {
|
||||||
|
// Clear the times if disabled
|
||||||
|
core::mem::take(&mut self.profile_times);
|
||||||
|
}
|
||||||
self.profiler.enable_timer = self.mode.profiler_enabled;
|
self.profiler.enable_timer = self.mode.profiler_enabled;
|
||||||
self.profiler.enable_debug_marker = self.mode.profiler_enabled;
|
self.profiler.enable_debug_marker = self.mode.profiler_enabled;
|
||||||
|
|
||||||
@ -395,6 +401,33 @@ impl Renderer {
|
|||||||
/// Get the render mode.
|
/// Get the render mode.
|
||||||
pub fn render_mode(&self) -> &RenderMode { &self.mode }
|
pub fn render_mode(&self) -> &RenderMode { &self.mode }
|
||||||
|
|
||||||
|
/// Get the current profiling times
|
||||||
|
/// Nested timings immediately follow their parent
|
||||||
|
/// Returns Vec<(how nested this timing is, label, length in seconds)>
|
||||||
|
pub fn timings(&self) -> Vec<(u8, &str, f64)> {
|
||||||
|
use wgpu_profiler::GpuTimerScopeResult;
|
||||||
|
fn recursive_collect<'a>(
|
||||||
|
vec: &mut Vec<(u8, &'a str, f64)>,
|
||||||
|
result: &'a GpuTimerScopeResult,
|
||||||
|
nest_level: u8,
|
||||||
|
) {
|
||||||
|
vec.push((
|
||||||
|
nest_level,
|
||||||
|
&result.label,
|
||||||
|
result.time.end - result.time.start,
|
||||||
|
));
|
||||||
|
result
|
||||||
|
.nested_scopes
|
||||||
|
.iter()
|
||||||
|
.for_each(|child| recursive_collect(vec, child, nest_level + 1));
|
||||||
|
}
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
self.profile_times
|
||||||
|
.iter()
|
||||||
|
.for_each(|child| recursive_collect(&mut vec, child, 0));
|
||||||
|
vec
|
||||||
|
}
|
||||||
|
|
||||||
/// Resize internal render targets to match window render target dimensions.
|
/// Resize internal render targets to match window render target dimensions.
|
||||||
pub fn on_resize(&mut self, dims: Vec2<u32>) -> Result<(), RenderError> {
|
pub fn on_resize(&mut self, dims: Vec2<u32>) -> Result<(), RenderError> {
|
||||||
// Avoid panics when creating texture with w,h of 0,0.
|
// Avoid panics when creating texture with w,h of 0,0.
|
||||||
@ -823,6 +856,13 @@ impl Renderer {
|
|||||||
"start_recording_frame",
|
"start_recording_frame",
|
||||||
"Renderer::start_recording_frame"
|
"Renderer::start_recording_frame"
|
||||||
);
|
);
|
||||||
|
// Try to get the latest profiling results
|
||||||
|
if self.mode.profiler_enabled {
|
||||||
|
// Note: this lags a few frames behind
|
||||||
|
if let Some(profile_times) = self.profiler.process_finished_frame() {
|
||||||
|
self.profile_times = profile_times;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: does this make sense here?
|
// TODO: does this make sense here?
|
||||||
self.device.poll(wgpu::Maintain::Poll);
|
self.device.poll(wgpu::Maintain::Poll);
|
||||||
@ -1098,18 +1138,9 @@ impl Renderer {
|
|||||||
//pub fn create_screenshot(&mut self) -> Result<image::DynamicImage,
|
//pub fn create_screenshot(&mut self) -> Result<image::DynamicImage,
|
||||||
// RenderError> {
|
// RenderError> {
|
||||||
pub fn create_screenshot(&mut self) {
|
pub fn create_screenshot(&mut self) {
|
||||||
// TODO: check if profiler enabled
|
|
||||||
// TODO: save alongside a screenshot
|
// TODO: save alongside a screenshot
|
||||||
// Ensure timestamp query data buffers are mapped
|
|
||||||
self.device.poll(wgpu::Maintain::Wait);
|
|
||||||
// Take profiler snapshot
|
// Take profiler snapshot
|
||||||
let profiling_data = if let Some(data) = self.profiler.process_finished_frame() {
|
if self.mode.profiler_enabled {
|
||||||
data
|
|
||||||
} else {
|
|
||||||
error!("Failed to retrieve profiling data");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let file_name = format!(
|
let file_name = format!(
|
||||||
"frame-trace_{}.json",
|
"frame-trace_{}.json",
|
||||||
std::time::SystemTime::now()
|
std::time::SystemTime::now()
|
||||||
@ -1118,12 +1149,15 @@ impl Renderer {
|
|||||||
.unwrap_or(0)
|
.unwrap_or(0)
|
||||||
);
|
);
|
||||||
|
|
||||||
wgpu_profiler::chrometrace::write_chrometrace(
|
if let Err(err) = wgpu_profiler::chrometrace::write_chrometrace(
|
||||||
std::path::Path::new(&file_name),
|
std::path::Path::new(&file_name),
|
||||||
&profiling_data,
|
&self.profile_times,
|
||||||
);
|
) {
|
||||||
|
error!("Failed to save GPU timing snapshot");
|
||||||
println!("{}", file_name);
|
} else {
|
||||||
|
info!("Saved GPU timing snapshot as: {}", file_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
//todo!()
|
//todo!()
|
||||||
// let (width, height) = self.get_resolution().into_tuple();
|
// let (width, height) = self.get_resolution().into_tuple();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user