gpu-trace-perf 1.5.0

Plays a collection of GPU traces under different environments to evaluate driver changes on performance
use anyhow::{Context, Result, bail};
use regex::Regex;

use crate::{Replay, ReplayOutput, replay_command};

pub struct GfxreconstructTrace {
    file: String,
}

impl GfxreconstructTrace {
    pub fn new(file: &str) -> GfxreconstructTrace {
        GfxreconstructTrace {
            file: file.to_owned(),
        }
    }
}

impl Replay for GfxreconstructTrace {
    fn replay(&self, wrapper: Option<&str>, envs: &[(String, String)]) -> Result<ReplayOutput> {
        let gfxr_command = ["gfxrecon-replay", "--swapchain", "offscreen", &self.file];

        let command = replay_command(&gfxr_command, wrapper, envs);
        let output: ReplayOutput = self.run_replay_command(command);

        if !output.status.success() {
            bail!("Failed to start gfxrecon-replay");
        }
        Ok(output)
    }

    fn fps(&self, output: &crate::ReplayOutput) -> Result<f64> {
        parse_gfxrecon_fps_output(&output.stdout)
    }

    fn name(&self) -> &str {
        &self.file
    }
}

// Returns the FPS for the frame from gpu-trace-perf-renderdoc-wrapper.py output
fn parse_gfxrecon_fps_output(output: &str) -> Result<f64> {
    lazy_static! {
        static ref CALL_RE: Regex = Regex::new("Replay FPS: ([0-9.]*) fps,").unwrap();
    }

    for line in output.lines() {
        if let Some(cap) = CALL_RE.captures(line) {
            return cap[1]
                .parse::<f64>()
                .with_context(|| format!("Parsing gfxrecon FPS: {}", line));
        }
    }

    anyhow::bail!("Failed to find replay FPS line");
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_gfxrecon_parsing() {
        let gfxrecon_input = "
[gfxrecon] INFO - Loading state for captured frame 2
[gfxrecon] INFO - Finished loading state for captured frame 2
Load time:  1.853056 seconds
Total time: 2.019838 seconds
Replay FPS: 59.958586 fps, 0.166782 seconds, 10 frames, framerange 2-11
";
        assert_eq!(
            parse_gfxrecon_fps_output(gfxrecon_input).unwrap(),
            59.958586
        );
    }
}