render: Add 'renderdoc' feature/module for manual frame capture

This feature is disabled by default. When enabled, you can use
`ruffle_render::renderdoc::begin_frame_capture` and
`ruffle_render::renderdoc::end_frame_capture` to manually trigger
a RenderDoc frame capture (if Ruffle wasn't launched by RenderDoc,
this logs an error).

This is very useful when debugging Stage3D/PixelBender bugs, as you
can produce a capture containing only the relevant graphics calls.
This commit is contained in:
Aaron Hill 2023-06-10 19:25:03 -05:00
parent b77c1fc78f
commit 26101ae979
4 changed files with 72 additions and 0 deletions

34
Cargo.lock generated
View File

@ -1544,6 +1544,15 @@ dependencies = [
"miniz_oxide 0.7.1",
]
[[package]]
name = "float-cmp"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
dependencies = [
"num-traits",
]
[[package]]
name = "float_next_after"
version = "0.1.5"
@ -3671,6 +3680,21 @@ dependencies = [
"memchr",
]
[[package]]
name = "renderdoc"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "272da9ec1e28b0ef17df4dcefad820b13f098ebe9c82697111fc57ccff621e12"
dependencies = [
"bitflags 1.3.2",
"float-cmp",
"libloading 0.7.4",
"once_cell",
"renderdoc-sys",
"winapi",
"wio",
]
[[package]]
name = "renderdoc-sys"
version = "1.0.0"
@ -3849,6 +3873,7 @@ dependencies = [
"num-derive",
"num-traits",
"png",
"renderdoc",
"ruffle_wstr",
"serde",
"smallvec",
@ -5652,6 +5677,15 @@ dependencies = [
"winapi",
]
[[package]]
name = "wio"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5"
dependencies = [
"winapi",
]
[[package]]
name = "x11-dl"
version = "2.21.0"

View File

@ -30,6 +30,11 @@ num-derive = "0.3"
byteorder = "1.4"
wgpu = { workspace = true, optional = true }
# This crate has a `compile_error!` on apple platforms
[target.'cfg(not(target_vendor = "apple"))'.dependencies.renderdoc]
version = "0.11.0"
optional = true
[dependencies.jpeg-decoder]
version = "0.3.0"
default-features = false # can't use rayon on web

View File

@ -6,6 +6,9 @@ pub mod error;
pub mod filters;
pub mod matrix;
pub mod pixel_bender;
// The `renderdoc` crate doesn't compile on apple platforms
#[cfg(all(feature = "renderdoc", not(target_vendor = "apple")))]
pub mod renderdoc;
pub mod shader_source;
pub mod shape_utils;
pub mod transform;

30
render/src/renderdoc.rs Normal file
View File

@ -0,0 +1,30 @@
use std::cell::RefCell;
use renderdoc::RenderDoc;
thread_local! {
pub static RENDERDOC: RefCell<Option<Result<RenderDoc<renderdoc::V141>, renderdoc::Error>>> = RefCell::new(None);
}
pub fn start_frame_capture() {
RENDERDOC.with(|renderdoc_cell| {
let mut write = renderdoc_cell.borrow_mut();
let renderdoc = write.get_or_insert_with(RenderDoc::new);
match renderdoc {
Ok(renderdoc) => renderdoc.start_frame_capture(std::ptr::null(), std::ptr::null()),
Err(e) => tracing::error!("Renderdoc was not initialized: {:?}", e),
}
})
}
pub fn end_frame_capture() {
RENDERDOC.with(|renderdoc_cell| {
let mut write = renderdoc_cell.borrow_mut();
let renderdoc = write.as_mut().expect("start_frame_capture was not called");
// We already logged an error in `start_frame_capture` if Renderdoc wasn't initialized,
// so there's no need to log one again here
if let Ok(renderdoc) = renderdoc {
renderdoc.end_frame_capture(std::ptr::null(), std::ptr::null());
}
})
}