From 5c8d06dba4d1feab235ea6a8cbb28a8bd4eeb3e7 Mon Sep 17 00:00:00 2001 From: Asuro Date: Wed, 3 Nov 2021 05:01:47 +0100 Subject: [PATCH] performance testing --- .../nsight-rust-engine-release.ngfx-proj | 129 ++++++++++++++++++ build/release.rdbg | Bin 0 -> 299 bytes ...erdoc-settings.cap => renderdoc-debug.cap} | 0 build/renderdoc-release.cap | 27 ++++ config/graphics.toml | 3 +- src/game/entities.rs | 24 +++- src/perf.rs | 8 +- src/vulkan/mod.rs | 21 ++- 8 files changed, 195 insertions(+), 17 deletions(-) create mode 100644 build/nsight-rust-engine-release/nsight-rust-engine-release.ngfx-proj create mode 100644 build/release.rdbg rename build/{renderdoc-settings.cap => renderdoc-debug.cap} (100%) create mode 100644 build/renderdoc-release.cap diff --git a/build/nsight-rust-engine-release/nsight-rust-engine-release.ngfx-proj b/build/nsight-rust-engine-release/nsight-rust-engine-release.ngfx-proj new file mode 100644 index 0000000..c53c3e8 --- /dev/null +++ b/build/nsight-rust-engine-release/nsight-rust-engine-release.ngfx-proj @@ -0,0 +1,129 @@ +{ + "extension": "ngfx-proj", + "files": [ + ], + "launcher": { + "activity/cpp/d3d/d3d12replayfencebehavior": "Default", + "activity/cpp/d3d/enablecachedpipelinestatesupport": false, + "activity/cpp/d3d/replaycapturedexecuteindirectbuffer": false, + "activity/cpp/d3d/reportforcefailedqueryinterfaces": true, + "activity/cpp/d3d/reportunknownobjects": true, + "activity/cpp/d3d/revisionzerodatacollection": true, + "activity/cpp/d3d/syncinterval": "0", + "activity/cpp/d3d/syncshadercollection": false, + "activity/cpp/forcerepaint": false, + "activity/cpp/opengl/delimiter": "SwapBuffers", + "activity/cpp/opengl/noerror": "Application Controlled", + "activity/cpp/raytracing/acceleration_structure_collect_to_vidmem": false, + "activity/cpp/raytracing/acceleration_structure_geometry_tracking_mode": "Auto", + "activity/cpp/raytracing/acceleration_structure_report_shallow_geometry_tracking_warnings": true, + "activity/cpp/troubleshooting/blockonfirstincompatibility": "Auto", + "activity/cpp/troubleshooting/crashreporting": true, + "activity/cpp/troubleshooting/ignoreincompatibilities": false, + "activity/cpp/troubleshooting/replaythreadpausestrategy": "Auto", + "activity/cpp/troubleshooting/serialization": true, + "activity/cpp/troubleshooting/threading": false, + "activity/cpp/vulkan/bufferdeviceaddresscapturereplay": true, + "activity/cpp/vulkan/coherentbuffercollection": true, + "activity/cpp/vulkan/forcedvalidationlayers": "VK_LAYER_LUNARG_parameter_validation; VK_LAYER_LUNARG_object_tracker; VK_LAYER_LUNARG_core_validation; VK_LAYER_KHRONOS_validation", + "activity/cpp/vulkan/forcevalidation": false, + "activity/cpp/vulkan/reserveheap": "0", + "activity/cpp/vulkan/revisionzerodatacollection": true, + "activity/cpp/vulkan/safeobjectlookup": "Auto", + "activity/cpp/vulkan/serializationobjectset": "Only Active", + "activity/cpp/vulkan/unsafepnext": false, + "activity/cpp/vulkan/unweavethreads": false, + "activity/fd/d3d/d3d12replayfencebehavior": "Default", + "activity/fd/d3d/enablecachedpipelinestatesupport": false, + "activity/fd/d3d/replaycapturedexecuteindirectbuffer": false, + "activity/fd/d3d/reportforcefailedqueryinterfaces": true, + "activity/fd/d3d/reportunknownobjects": true, + "activity/fd/d3d/revisionzerodatacollection": true, + "activity/fd/d3d/syncinterval": "0", + "activity/fd/d3d/syncshadercollection": false, + "activity/fd/forcerepaint": false, + "activity/fd/opengl/delimiter": "SwapBuffers", + "activity/fd/opengl/noerror": "Application Controlled", + "activity/fd/raytracing/acceleration_structure_collect_to_vidmem": false, + "activity/fd/raytracing/acceleration_structure_geometry_tracking_mode": "Auto", + "activity/fd/raytracing/acceleration_structure_report_shallow_geometry_tracking_warnings": true, + "activity/fd/targethud": true, + "activity/fd/troubleshooting/blockonfirstincompatibility": "Auto", + "activity/fd/troubleshooting/collectlinetables": true, + "activity/fd/troubleshooting/collectsassassembly": true, + "activity/fd/troubleshooting/crashreporting": true, + "activity/fd/troubleshooting/driverinstrumentation": true, + "activity/fd/troubleshooting/hardwarepmmetrics": true, + "activity/fd/troubleshooting/ignoreincompatibilities": false, + "activity/fd/troubleshooting/replaythreadpausestrategy": "Auto", + "activity/fd/troubleshooting/serialization": true, + "activity/fd/troubleshooting/shaderreflection": true, + "activity/fd/troubleshooting/threading": false, + "activity/fd/vulkan/bufferdeviceaddresscapturereplay": true, + "activity/fd/vulkan/coherentbuffercollection": true, + "activity/fd/vulkan/forcedvalidationlayers": "VK_LAYER_LUNARG_parameter_validation; VK_LAYER_LUNARG_object_tracker; VK_LAYER_LUNARG_core_validation; VK_LAYER_KHRONOS_validation", + "activity/fd/vulkan/forcevalidation": false, + "activity/fd/vulkan/reserveheap": "0", + "activity/fd/vulkan/revisionzerodatacollection": true, + "activity/fd/vulkan/safeobjectlookup": "Auto", + "activity/fd/vulkan/serializationobjectset": "Only Active", + "activity/fd/vulkan/unsafepnext": false, + "activity/fd/vulkan/unweavethreads": false, + "activity/fp/d3d/d3d12replayfencebehavior": "Default", + "activity/fp/d3d/enablecachedpipelinestatesupport": false, + "activity/fp/d3d/replaycapturedexecuteindirectbuffer": false, + "activity/fp/d3d/reportforcefailedqueryinterfaces": true, + "activity/fp/d3d/reportunknownobjects": true, + "activity/fp/d3d/revisionzerodatacollection": true, + "activity/fp/d3d/syncinterval": "0", + "activity/fp/d3d/syncshadercollection": false, + "activity/fp/forcerepaint": false, + "activity/fp/opengl/delimiter": "SwapBuffers", + "activity/fp/opengl/noerror": "Application Controlled", + "activity/fp/raytracing/acceleration_structure_collect_to_vidmem": false, + "activity/fp/raytracing/acceleration_structure_geometry_tracking_mode": "Auto", + "activity/fp/raytracing/acceleration_structure_report_shallow_geometry_tracking_warnings": true, + "activity/fp/targethud": true, + "activity/fp/troubleshooting/blockonfirstincompatibility": "Auto", + "activity/fp/troubleshooting/collectlinetables": true, + "activity/fp/troubleshooting/collectsassassembly": true, + "activity/fp/troubleshooting/crashreporting": true, + "activity/fp/troubleshooting/driverinstrumentation": true, + "activity/fp/troubleshooting/hardwarepmmetrics": true, + "activity/fp/troubleshooting/ignoreincompatibilities": false, + "activity/fp/troubleshooting/replaythreadpausestrategy": "Auto", + "activity/fp/troubleshooting/serialization": true, + "activity/fp/troubleshooting/shaderreflection": true, + "activity/fp/troubleshooting/threading": false, + "activity/fp/vulkan/bufferdeviceaddresscapturereplay": true, + "activity/fp/vulkan/coherentbuffercollection": true, + "activity/fp/vulkan/forcedvalidationlayers": "VK_LAYER_LUNARG_parameter_validation; VK_LAYER_LUNARG_object_tracker; VK_LAYER_LUNARG_core_validation; VK_LAYER_KHRONOS_validation", + "activity/fp/vulkan/forcevalidation": false, + "activity/fp/vulkan/reserveheap": "0", + "activity/fp/vulkan/revisionzerodatacollection": true, + "activity/fp/vulkan/safeobjectlookup": "Auto", + "activity/fp/vulkan/serializationobjectset": "Only Active", + "activity/fp/vulkan/unsafepnext": false, + "activity/fp/vulkan/unweavethreads": false, + "activity/warpviz/general/capturemode": "Frames", + "activity/warpviz/general/framecount": "1", + "activity/warpviz/general/lockclockstobase": true, + "activity/warpviz/general/metricset": "Throughput Metrics", + "activity/warpviz/general/timestampcount": "100000", + "activity/warpviz/general/vsyncmode": "Off", + "platform/win32/arguments": "", + "platform/win32/autoconnect": true, + "platform/win32/environment": "", + "platform/win32/executable": "D:/Code/rust-engine/target/release/rust-engine.exe", + "platform/win32/executable/history": [ + "D:/Code/rust-engine/target/release/rust-engine.exe" + ], + "platform/win32/workingdir": "D:/Code/rust-engine", + "platform/win32/workingdir/history": [ + "D:/Code/rust-engine" + ], + "platform/windows/device": "localhost" + }, + "uuid": "{880d147e-f91a-47ff-945f-b4a3c2771050}", + "version": "1.2" +} diff --git a/build/release.rdbg b/build/release.rdbg new file mode 100644 index 0000000000000000000000000000000000000000..2f383d2c66f7e64899276c1d53f7f7b1f30d3f7c GIT binary patch literal 299 zcmWG?adJ0eU|?{uigC_QNsTEgEiTbb%}dYBON}W>EJ{x;i786WNlh$9kLV51_lNIOi(?Z literal 0 HcmV?d00001 diff --git a/build/renderdoc-settings.cap b/build/renderdoc-debug.cap similarity index 100% rename from build/renderdoc-settings.cap rename to build/renderdoc-debug.cap diff --git a/build/renderdoc-release.cap b/build/renderdoc-release.cap new file mode 100644 index 0000000..f52363f --- /dev/null +++ b/build/renderdoc-release.cap @@ -0,0 +1,27 @@ +{ + "rdocCaptureSettings": 1, + "settings": { + "autoStart": false, + "commandLine": "", + "environment": [ + ], + "executable": "D:\\Code\\rust-engine\\target\\release\\rust-engine.exe", + "inject": false, + "numQueuedFrames": 0, + "options": { + "allowFullscreen": true, + "allowVSync": true, + "apiValidation": true, + "captureAllCmdLists": false, + "captureCallstacks": true, + "captureCallstacksOnlyDraws": false, + "debugOutputMute": true, + "delayForDebugger": 0, + "hookIntoChildren": false, + "refAllResources": false, + "verifyBufferAccess": true + }, + "queuedFrameCap": 0, + "workingDir": "D:\\Code\\rust-engine" + } +} diff --git a/config/graphics.toml b/config/graphics.toml index cbbe4e8..0f96cd1 100644 --- a/config/graphics.toml +++ b/config/graphics.toml @@ -1 +1,2 @@ -msaa_samples = 4 \ No newline at end of file +msaa_samples = 4 +vsync = "Mailbox" \ No newline at end of file diff --git a/src/game/entities.rs b/src/game/entities.rs index 08ca2f4..62fa71e 100644 --- a/src/game/entities.rs +++ b/src/game/entities.rs @@ -1,6 +1,6 @@ use cgmath::{Vector4, vec4}; -use crate::{input::InputState, text::{create_text_object, update_text}, vulkan::{MeshHandle, TextVertex, Vertex, VulkanRenderer, gameobject::{GameObject, GameObjectHandle, Updatable}, mesh::{CPUMesh, CPUVertexList}}}; +use crate::{input::InputState, perf::stddev, text::{create_text_object, update_text}, vulkan::{MeshHandle, TextVertex, Vertex, VulkanRenderer, gameobject::{GameObject, GameObjectHandle, Updatable}, mesh::{CPUMesh, CPUVertexList}}}; use super::{GameState, TestGame}; @@ -23,17 +23,31 @@ impl Updatable for FpsCounter { go.visible = !go.visible; } - self.text.clear(); unsafe { + let mut counters = vec![]; + self.text.clear(); + if let Some(pcs) = &crate::perf::PERF_COUNTERS { for (name, pc) in pcs { let mean = pc.mean(); - let stddev = pc.stddev(mean as i128); - self.text.push_str(&format!("{}: {:.1}ms (±{:.1})\n", name, (mean as f64) / 1000., stddev / 1000.)); + let stddev = stddev(&pc.values, mean as i128); + let str = format!("{}: {:.1}ms (±{:.1})\n", name, (mean as f64) / 1000., stddev / 1000.); + counters.push((mean, str)); } } + + counters.sort_by(|a, b| a.cmp(b)); + for (_, str) in counters { + self.text.push_str(&str); + } + + let frame_time_mean: u128 = renderer.fps_counter.iter().sum::() / crate::perf::PERF_COUNTER_SIZE as u128; + let fps_mean = 1000000. / frame_time_mean as f64; + let fps_min = 1000000. / *renderer.fps_counter.iter().max().unwrap() as f64; + + self.text.push_str(&format!("Total FPS: {:.0} (min {:.0})", fps_mean, fps_min)); } - update_text(self.game_object, &self.text, 30., renderer, &mut game_state.brush, game_objects); + update_text(self.game_object, &self.text, 20., renderer, &mut game_state.brush, game_objects); } } diff --git a/src/perf.rs b/src/perf.rs index 458f692..fee2016 100644 --- a/src/perf.rs +++ b/src/perf.rs @@ -8,15 +8,15 @@ pub struct PerformanceCounter { pub index: usize, } +pub fn stddev(arr: &[u128; PERF_COUNTER_SIZE], mean: i128) -> f64 { + f64::sqrt(arr.iter().fold(0, |acc, b| acc + (*b as i128 - mean) * (*b as i128 - mean)) as f64 / PERF_COUNTER_SIZE as f64) +} + impl PerformanceCounter { pub fn mean(&self) -> u128 { self.values.iter().sum::() / PERF_COUNTER_SIZE as u128 } - pub fn stddev(&self, mean: i128) -> f64 { - f64::sqrt(self.values.iter().fold(0, |acc, b| acc + (*b as i128 - mean) * (*b as i128 - mean)) as f64 / PERF_COUNTER_SIZE as f64) - } - pub fn init_perf() { unsafe { if PERF_COUNTERS.is_none() { PERF_COUNTERS = Some(HashMap::new()); } diff --git a/src/vulkan/mod.rs b/src/vulkan/mod.rs index 69b2a8d..b6e5714 100644 --- a/src/vulkan/mod.rs +++ b/src/vulkan/mod.rs @@ -1,5 +1,5 @@ use std::sync::Arc; -use std::time::SystemTime; +use std::time::{Instant, SystemTime}; use cgmath::{Matrix4, SquareMatrix}; use dds::get_block_size; @@ -15,7 +15,7 @@ use vulkano::image::{ImageCreateFlags, ImageDimensions, ImmutableImage}; use vulkano::instance::{ApplicationInfo, Instance, InstanceExtensions, Version}; use vulkano::instance::debug::{DebugCallback, MessageSeverity, MessageType}; use vulkano::sampler::{Filter, MipmapMode, Sampler, SamplerAddressMode}; -use vulkano::swapchain::{AcquireError, FullscreenExclusive, PresentMode, Surface, SurfaceTransform, Swapchain, SwapchainCreationError}; +use vulkano::swapchain::{AcquireError, FullscreenExclusive, Surface, SurfaceTransform, Swapchain, SwapchainCreationError}; use vulkano::swapchain; use vulkano::sync::{FlushError, GpuFuture}; use vulkano::sync; @@ -30,7 +30,7 @@ use pipelines::vs; use winit::window::{Window, WindowBuilder}; use crate::config::RenderConfig; -use crate::perf::PerformanceCounter; +use crate::perf::{self, PerformanceCounter}; use crate::vulkan::gameobject::GameObject; use self::mesh::CPUVertexList; @@ -130,7 +130,10 @@ pub struct VulkanRenderer { pub previous_frame_end: Option>, pub uniform_buffers: Vec>>, pub render_config: RenderConfig, - pub viewport: Viewport + pub viewport: Viewport, + pub fps_counter: [u128; perf::PERF_COUNTER_SIZE], + pub fps_counter_index: usize, + pub fps_counter_instant: Instant, } impl VulkanRenderer { @@ -303,11 +306,12 @@ impl VulkanRenderer { pipelines, uniform_buffers, surface, swapchain, render_pass, queue, recreate_swapchain: false, debug_callback, previous_frame_end, - render_config, viewport + render_config, viewport, + fps_counter: [0; perf::PERF_COUNTER_SIZE], fps_counter_index: 0, fps_counter_instant: Instant::now() }, events_loop) } - // #[perf("cb", crate::perf::PerformanceCounter)] + #[perf("cb", crate::perf::PerformanceCounter)] fn create_command_buffer(self: &mut Self, fb_index: usize, uniform_buffer_data: &vs::ty::ObjectUniformData, game_objects: &Vec) -> Arc { // General setup let mut builder = AutoCommandBufferBuilder::primary(self.device.clone(), self.queue.family(), CommandBufferUsage::OneTimeSubmit).unwrap(); @@ -404,7 +408,7 @@ impl VulkanRenderer { .then_execute(self.queue.clone(), command_buffer).unwrap() .then_swapchain_present(self.queue.clone(), self.swapchain.clone(), fb_index) .then_signal_fence_and_flush(); - + match future { Ok(future) => { // we're joining on the previous future but the CPU is running faster than the GPU so @@ -683,6 +687,9 @@ pub fn start_event_loop(mut renderer: VulkanRenderer, mut game: Box, e Event::RedrawRequested(..) => { PerformanceCounter::perf_next_frame("renderer"); PerformanceCounter::perf_next_frame("cb"); + renderer.fps_counter[renderer.fps_counter_index] = renderer.fps_counter_instant.elapsed().as_micros(); + renderer.fps_counter_instant = Instant::now(); + renderer.fps_counter_index = (renderer.fps_counter_index + 1) % perf::PERF_COUNTER_SIZE; renderer.render_loop(game.get_ubo(), &game.get_game_objects()); }, Event::MainEventsCleared => {