Compare commits

..

4 Commits

Author SHA1 Message Date
5c8d06dba4 performance testing 2021-11-03 05:01:47 +01:00
d995d66f89 vsync 2021-11-03 05:01:42 +01:00
9125878840 fix macro 2021-11-03 01:56:34 +01:00
bee1b66b55 perf counter macros 2021-10-31 16:12:32 +01:00
16 changed files with 355 additions and 43 deletions

1
.gitignore vendored
View File

@@ -1,6 +1,7 @@
# Generated by Cargo
# will have compiled files and executables
/target/
/rust-engine-proc/target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html

View File

@@ -20,6 +20,7 @@ gilrs = "0.7"
gltf = "0.15"
glyph_brush = "0.7"
winapi = "0.3"
rust-engine-proc = { path = "rust-engine-proc" }
[profile.release]
debug = 1

View File

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

BIN
build/release.rdbg Normal file

Binary file not shown.

View File

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

View File

@@ -1 +1,2 @@
msaa_samples = 4
msaa_samples = 4
vsync = "Mailbox"

View File

@@ -0,0 +1,13 @@
[package]
name = "rust-engine-proc"
version = "0.1.0"
edition = "2018"
[lib]
proc-macro = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
syn = { version = "1.0", features = ["full"] }
quote = "1.0"

View File

@@ -0,0 +1,38 @@
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::{AttributeArgs, ItemFn, Lit, Meta, parse_macro_input, parse_quote};
#[proc_macro_attribute]
pub fn perf(attr: TokenStream, item: TokenStream) -> TokenStream {
let attrs = parse_macro_input!(attr as AttributeArgs);
let name = match &attrs[0] {
syn::NestedMeta::Lit(Lit::Str(l)) => l.value(),
_ => panic!("Invalid attribute"),
};
let counter_type = match &attrs[1] {
syn::NestedMeta::Meta(Meta::Path(p)) => p,
_ => panic!("Invalid attribute"),
};
let mut function = parse_macro_input!(item as ItemFn);
function.block.stmts.insert(0, parse_quote! {
let __perf_start = std::time::Instant::now();
});
let timer_end = parse_quote! {
unsafe {
#counter_type::write_perf(#name, __perf_start.elapsed().as_micros());
}
};
if let Some(last_stmt) = function.block.stmts.last() {
match last_stmt {
syn::Stmt::Expr(_) => function.block.stmts.insert(function.block.stmts.len() - 1, timer_end),
_ => function.block.stmts.push(timer_end),
}
} else {
function.block.stmts.push(timer_end);
}
quote!(#function).into()
}

View File

@@ -2,7 +2,7 @@ use std::{convert::TryInto, fs};
use serde_derive::{Deserialize, Serialize};
use toml;
use vulkano::image::SampleCount;
use vulkano::{image::SampleCount, swapchain::PresentMode};
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
pub struct LogConfigInput {
@@ -27,7 +27,8 @@ impl LogConfig {
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
pub struct RenderConfig {
pub msaa_samples: u32
pub msaa_samples: u32,
pub vsync: PresentModeConfig,
}
impl RenderConfig {
@@ -38,4 +39,23 @@ impl RenderConfig {
pub fn get_msaa(&self) -> Option<SampleCount> {
if self.msaa_samples > 0 { self.msaa_samples.try_into().ok() } else { None }
}
}
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
pub enum PresentModeConfig {
Immediate,
Mailbox,
Fifo,
FifoRelaxed,
}
impl Into<PresentMode> for PresentModeConfig {
fn into(self) -> PresentMode {
match self {
PresentModeConfig::Immediate => PresentMode::Immediate,
PresentModeConfig::Mailbox => PresentMode::Mailbox,
PresentModeConfig::Fifo => PresentMode::Fifo,
PresentModeConfig::FifoRelaxed => PresentMode::Relaxed,
}
}
}

View File

@@ -1,17 +1,18 @@
use cgmath::{Vector4, vec4};
use crate::{input::InputState, text::{create_text_object, update_text}, vulkan::{MeshHandle, PERF_COUNTER_SIZE, 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};
pub struct FpsCounter {
pub game_object: GameObjectHandle
pub game_object: GameObjectHandle,
pub text: String,
}
impl FpsCounter {
pub fn new(game: &mut TestGame, renderer: &mut VulkanRenderer) -> FpsCounter {
let text_mesh = create_text_object(&mut game.game_state.brush, renderer, "", 30.);
FpsCounter { game_object: game.add_game_object(renderer, text_mesh) }
FpsCounter { game_object: game.add_game_object(renderer, text_mesh), text: String::new() }
}
}
@@ -22,12 +23,31 @@ impl Updatable for FpsCounter {
go.visible = !go.visible;
}
let update_duration = renderer.game_data.update_perf_counters.iter().sum::<u128>() / PERF_COUNTER_SIZE as u128;
let render_duration = renderer.game_data.render_perf_counters.iter().sum::<u128>() / PERF_COUNTER_SIZE as u128;
let other_duration = renderer.game_data.other_perf_counters.iter().sum::<u128>() / PERF_COUNTER_SIZE as u128;
let other_variance = renderer.game_data.other_perf_counters.iter().fold(0, |acc, b| acc + (*b as i128 - other_duration as i128) * (*b as i128 - other_duration as i128)) / PERF_COUNTER_SIZE as i128;
let text = format!("Update: {:.0}ms\nRender: {:.0}ms\nTotal: {:.0}ms (±{:.1})\nDelta: {:.0}ms", update_duration as f64 / 1000., render_duration as f64 / 1000., other_duration as f64 / 1000., f64::sqrt(other_variance as f64) / 1000., _delta_time * 1000.);
update_text(self.game_object, &text, 30., renderer, &mut game_state.brush, game_objects);
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 = 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::<u128>() / 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, 20., renderer, &mut game_state.brush, game_objects);
}
}

View File

@@ -1,6 +1,7 @@
use std::time::Instant;
use cgmath::{Deg, Euler, Quaternion, vec3};
use glyph_brush::GlyphBrush;
use rust_engine_proc::perf;
use winit::event::Event;
use level::{load_level, save_level};
@@ -56,9 +57,8 @@ impl Game for TestGame {
self.input.on_window_event(event);
}
#[perf("update", crate::perf::PerformanceCounter)]
fn update(self: &mut Self, renderer: &mut VulkanRenderer) {
let precise_start = Instant::now();
// Input and timing
self.input.frame_start();
let time = (renderer.game_data.start_time.elapsed().unwrap().as_micros() as f64 / 1000000.0) as f32;
@@ -126,9 +126,6 @@ impl Game for TestGame {
_dummy1: [0; 4],
_dummy2: [0; 4],
};
let precise_duration = precise_start.elapsed().as_micros();
renderer.game_data.update_perf_counters[renderer.game_data.performance_counter_index] = precise_duration;
}
fn get_ubo(&self) -> &vs::ty::ObjectUniformData {

View File

@@ -8,6 +8,7 @@ use std::iter::FromIterator;
use cgmath::{InnerSpace, Vector2, Zero, vec2};
use gilrs;
use gilrs::{EventType, Gilrs};
use rust_engine_proc::perf;
use serde_derive::{Deserialize, Serialize};
use toml;
use winapi::shared::minwindef::UINT;
@@ -233,6 +234,7 @@ impl InputState {
return state;
}
#[perf("input_events", crate::perf::PerformanceCounter)]
pub fn on_window_event(self: &mut Self, event: &Event<()>) {
match event {
Event::WindowEvent { event: WindowEvent::KeyboardInput { device_id, input, .. }, .. } => {

View File

@@ -13,6 +13,7 @@ mod game;
mod tests;
mod text;
mod util;
mod perf;
fn main() {
let log_config = LogConfig::from_file("config/log.toml");

64
src/perf.rs Normal file
View File

@@ -0,0 +1,64 @@
use std::collections::HashMap;
pub const PERF_COUNTER_SIZE: usize = 100;
pub static mut PERF_COUNTERS: Option<HashMap<String, PerformanceCounter>> = None;
pub struct PerformanceCounter {
pub values: [u128; PERF_COUNTER_SIZE],
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::<u128>() / PERF_COUNTER_SIZE as u128
}
pub fn init_perf() {
unsafe {
if PERF_COUNTERS.is_none() { PERF_COUNTERS = Some(HashMap::new()); }
}
}
pub fn write_perf(name: &str, value: u128) {
unsafe {
if let Some(pcs) = &mut PERF_COUNTERS {
if let Some(pc) = pcs.get_mut(name) {
pc.values[pc.index] = value;
} else {
let mut pc = PerformanceCounter { values: [0; PERF_COUNTER_SIZE], index: 0 };
pc.values[0] = value;
pcs.insert(name.to_string(), pc);
}
}
}
}
pub fn _get_perf(name: &str) -> u128 {
unsafe {
if let Some(pcs) = &mut PERF_COUNTERS {
if let Some(pc) = pcs.get_mut(name) {
pc.mean()
} else {
0
}
} else {
0
}
}
}
pub fn perf_next_frame(name: &str) {
unsafe {
if let Some(pcs) = &mut PERF_COUNTERS {
if let Some(pc) = pcs.get_mut(name) {
pc.index = (pc.index + 1) % PERF_COUNTER_SIZE;
pc.values[pc.index] = 0;
}
}
}
}
}

View File

@@ -1,8 +1,9 @@
use std::{sync::Arc, time::Instant};
use std::time::SystemTime;
use std::sync::Arc;
use std::time::{Instant, SystemTime};
use cgmath::{Matrix4, SquareMatrix};
use dds::get_block_size;
use rust_engine_proc::perf;
use vulkano::device::physical::PhysicalDevice;
use vulkano::pipeline::viewport::Viewport;
use vulkano::render_pass::{FramebufferAbstract, RenderPass};
@@ -14,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;
@@ -29,6 +30,7 @@ use pipelines::vs;
use winit::window::{Window, WindowBuilder};
use crate::config::RenderConfig;
use crate::perf::{self, PerformanceCounter};
use crate::vulkan::gameobject::GameObject;
use self::mesh::CPUVertexList;
@@ -44,8 +46,6 @@ const VALIDATION_LAYERS: &[&str] = &[
"VK_LAYER_KHRONOS_validation",
];
pub const PERF_COUNTER_SIZE: usize = 1000;
#[derive(Default, Debug, Clone)]
pub struct Vertex {
pub position: [f32; 3],
@@ -114,11 +114,6 @@ pub struct GameData {
pub meshes: Vec<Mesh<Vertex>>,
pub meshes_text: Vec<Mesh<TextVertex>>,
pub textures: Vec<Texture>,
pub update_perf_counters: [u128; PERF_COUNTER_SIZE],
pub render_perf_counters: [u128; PERF_COUNTER_SIZE],
pub other_perf_counters: [u128; PERF_COUNTER_SIZE],
pub other_perf_instant: Instant,
pub performance_counter_index: usize,
}
pub struct VulkanRenderer {
@@ -135,7 +130,10 @@ pub struct VulkanRenderer {
pub previous_frame_end: Option<Box<dyn GpuFuture>>,
pub uniform_buffers: Vec<Arc<CpuAccessibleBuffer<vs::ty::ObjectUniformData>>>,
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 {
@@ -149,11 +147,6 @@ impl VulkanRenderer {
meshes: vec![],
meshes_text: vec![],
textures: vec![],
update_perf_counters: [0; PERF_COUNTER_SIZE],
render_perf_counters: [0; PERF_COUNTER_SIZE],
other_perf_counters: [0; PERF_COUNTER_SIZE],
performance_counter_index: 0,
other_perf_instant: Instant::now(),
};
// Create basic vulkan instance with layers and info
@@ -255,7 +248,7 @@ impl VulkanRenderer {
.sharing_mode(&queue)
.transform(SurfaceTransform::Identity)
.composite_alpha(alpha)
.present_mode(PresentMode::Fifo)
.present_mode(render_config.vsync.into())
.fullscreen_exclusive(FullscreenExclusive::Default)
.clipped(true)
.color_space(color_space)
@@ -313,10 +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)]
fn create_command_buffer(self: &mut Self, fb_index: usize, uniform_buffer_data: &vs::ty::ObjectUniformData, game_objects: &Vec<GameObject>) -> Arc<PrimaryAutoCommandBuffer> {
// General setup
let mut builder = AutoCommandBufferBuilder::primary(self.device.clone(), self.queue.family(), CommandBufferUsage::OneTimeSubmit).unwrap();
@@ -342,9 +337,8 @@ impl VulkanRenderer {
Arc::new(builder.build().unwrap())
}
#[perf("renderer", crate::perf::PerformanceCounter)]
pub fn render_loop(self: &mut Self, new_ubo: &vs::ty::ObjectUniformData, game_objects: &Vec<GameObject>) {
let precise_start = Instant::now();
// cleanup previous frame
self.previous_frame_end.as_mut().unwrap().cleanup_finished();
@@ -414,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
@@ -438,8 +432,6 @@ impl VulkanRenderer {
self.previous_frame_end = Some(Box::new(sync::now(self.device.clone())) as Box<_>);
}
};
self.game_data.render_perf_counters[self.game_data.performance_counter_index] = precise_start.elapsed().as_micros();
}
pub fn upload_mesh(self: &mut Self, mesh: CPUMesh, original_path: Option<String>) -> usize {
@@ -676,6 +668,8 @@ impl VulkanRenderer {
}
pub fn start_event_loop(mut renderer: VulkanRenderer, mut game: Box<dyn Game>, event_loop: EventLoop<()>) {
PerformanceCounter::init_perf();
event_loop.run(move |event, _, control_flow| {
game.on_window_event(&event);
@@ -691,12 +685,16 @@ pub fn start_event_loop(mut renderer: VulkanRenderer, mut game: Box<dyn Game>, e
renderer.recreate_swapchain = true;
},
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());
renderer.game_data.other_perf_counters[renderer.game_data.performance_counter_index] = renderer.game_data.other_perf_instant.elapsed().as_micros();
renderer.game_data.other_perf_instant = Instant::now();
renderer.game_data.performance_counter_index = (renderer.game_data.performance_counter_index + 1) % PERF_COUNTER_SIZE;
},
Event::MainEventsCleared => {
PerformanceCounter::perf_next_frame("update");
PerformanceCounter::perf_next_frame("input_events");
game.update(&mut renderer);
renderer.surface.window().request_redraw();
},