Add Verbosity Flags to wgpu-info (#4995)

This commit is contained in:
Connor Fitzgerald 2024-01-05 03:24:16 -05:00 committed by GitHub
parent f162cfa0f8
commit 0b20427601
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 81 additions and 17 deletions

View File

@ -488,7 +488,7 @@ jobs:
export RUST_LOG=trace
# This needs to match the command in xtask/tests.rs
cargo llvm-cov --no-cfg-coverage --no-report run --bin wgpu-info
cargo llvm-cov --no-cfg-coverage --no-report run --bin wgpu-info -- -vv
- name: run tests
shell: bash

View File

@ -2,12 +2,23 @@ use std::{io, process::exit};
use anyhow::Context;
use crate::human::PrintingVerbosity;
const HELP: &str = "\
Usage: wgpu-info [--input <PATH>] [--output <PATH>] [--json]
Usage: wgpu-info [--input <PATH>] [--output <PATH>] [-q/-v/-vv/--json]
Information Density:
These settings have no effect on the JSON output. The highest verbosity
provided will be used if multiple are passed.
-q Quiet mode, only print the names and backends of the adapters.
[default] Print the adapter info.
-v Additionally print all features, limits, and downlevel capabilities.
-vv Additionally print all texture capabilities and flags.
Options:
-h, --help Print this help message.
-i, --input <PATH> Source to read JSON report from. (\"-\" reads from stdin)
-i, --input <PATH> Read a json report to make it human readable. (\"-\" reads from stdin)
-o, --output <PATH> Destination to write output to. (\"-\" writes to stdout)
-j, --json Output JSON information instead of human-readable text.
";
@ -31,6 +42,23 @@ pub fn main() -> anyhow::Result<()> {
let output_path: Option<String> = args.opt_value_from_str(["-o", "--output"]).unwrap();
let json = args.contains(["-j", "--json"]);
let verbosity = if args.contains("-vv") {
PrintingVerbosity::InformationFeaturesLimitsTexture
} else if args.contains("-v") {
PrintingVerbosity::InformationFeaturesLimits
} else if args.contains("-q") {
PrintingVerbosity::NameOnly
} else {
PrintingVerbosity::Information
};
// Binary OR is intentional, we want all flags to be consumed every iteration.
while args.contains("-vv") | args.contains("-v") | args.contains("-q") {
eprintln!(
"Warning: More than one verbosity flag was passed. Using the most verbose option."
);
}
let remaining = args.finish();
if !remaining.is_empty() {
eprint!("Unknown argument(s): ");
@ -82,7 +110,7 @@ pub fn main() -> anyhow::Result<()> {
.into_json(output)
.with_context(|| format!("Failed to write to output: {output_name}"))?;
} else {
crate::human::print_adapters(&mut output, &report)
crate::human::print_adapters(&mut output, &report, verbosity)
.with_context(|| format!("Failed to write to output: {output_name}"))?;
}

View File

@ -53,9 +53,29 @@ trait FlagsExt: Flags {
impl<T> FlagsExt for T where T: Flags {}
fn print_empty_string(input: &str) -> &str {
if input.is_empty() {
"<empty>"
} else {
input
}
}
#[derive(Debug, Clone, Copy)]
pub enum PrintingVerbosity {
/// Corresponds to the `-q` flag
NameOnly,
/// Corresponds to no flag.
Information,
/// Corresponds to the `-v` flag
InformationFeaturesLimits,
/// Corresponds to the `-vv` flag
InformationFeaturesLimitsTexture,
}
// Lets keep these print statements on one line
#[rustfmt::skip]
fn print_adapter(output: &mut impl io::Write, report: &AdapterReport, idx: usize) -> io::Result<()> {
fn print_adapter(output: &mut impl io::Write, report: &AdapterReport, idx: usize, verbosity: PrintingVerbosity) -> io::Result<()> {
let AdapterReport {
info,
features,
@ -69,15 +89,24 @@ fn print_adapter(output: &mut impl io::Write, report: &AdapterReport, idx: usize
// Adapter Info //
//////////////////
if matches!(verbosity, PrintingVerbosity::NameOnly) {
writeln!(output, "Adapter {idx}: {} ({:?})", info.name, info.backend)?;
return Ok(());
}
writeln!(output, "Adapter {idx}:")?;
writeln!(output, "\t Backend: {:?}", info.backend)?;
writeln!(output, "\t Name: {:?}", info.name)?;
writeln!(output, "\t VendorID: {:?}", info.vendor)?;
writeln!(output, "\t DeviceID: {:?}", info.device)?;
writeln!(output, "\t Type: {:?}", info.device_type)?;
writeln!(output, "\t Driver: {:?}", info.driver)?;
writeln!(output, "\tDriverInfo: {:?}", info.driver_info)?;
writeln!(output, "\t Compliant: {:?}", downlevel.is_webgpu_compliant())?;
writeln!(output, "\t Backend: {:?}", info.backend)?;
writeln!(output, "\t Name: {}", info.name)?;
writeln!(output, "\t VendorID: {:#X?}", info.vendor)?;
writeln!(output, "\t DeviceID: {:#X?}", info.device)?;
writeln!(output, "\t Type: {:?}", info.device_type)?;
writeln!(output, "\t Driver: {}", print_empty_string(&info.driver))?;
writeln!(output, "\t DriverInfo: {}", print_empty_string(&info.driver_info))?;
writeln!(output, "\tWebGPU Compliant: {:?}", downlevel.is_webgpu_compliant())?;
if matches!(verbosity, PrintingVerbosity::Information) {
return Ok(());
}
//////////////
// Features //
@ -166,16 +195,19 @@ fn print_adapter(output: &mut impl io::Write, report: &AdapterReport, idx: usize
writeln!(output, "\tDownlevel Properties:")?;
let wgpu::DownlevelCapabilities {
shader_model,
shader_model: _,
limits: _,
flags,
} = downlevel;
writeln!(output, "\t\t Shader Model: {shader_model:?}")?;
let max_downlevel_flag_width = wgpu::DownlevelFlags::max_debug_print_width();
for bit in wgpu::DownlevelFlags::all().iter() {
writeln!(output, "\t\t{:>width$}: {}", bit.name(), flags.contains(bit), width = max_downlevel_flag_width)?;
};
if matches!(verbosity, PrintingVerbosity::InformationFeaturesLimits) {
return Ok(());
}
////////////////////
// Texture Usages //
////////////////////
@ -237,9 +269,13 @@ fn print_adapter(output: &mut impl io::Write, report: &AdapterReport, idx: usize
Ok(())
}
pub fn print_adapters(output: &mut impl io::Write, report: &GpuReport) -> io::Result<()> {
pub fn print_adapters(
output: &mut impl io::Write,
report: &GpuReport,
verbosity: PrintingVerbosity,
) -> io::Result<()> {
for (idx, adapter) in report.devices.iter().enumerate() {
print_adapter(output, adapter, idx)?;
print_adapter(output, adapter, idx, verbosity)?;
}
Ok(())
}