summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wgpu-hal/src/auxil/renderdoc.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /third_party/rust/wgpu-hal/src/auxil/renderdoc.rs
parentInitial commit. (diff)
downloadfirefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz
firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/wgpu-hal/src/auxil/renderdoc.rs')
-rw-r--r--third_party/rust/wgpu-hal/src/auxil/renderdoc.rs141
1 files changed, 141 insertions, 0 deletions
diff --git a/third_party/rust/wgpu-hal/src/auxil/renderdoc.rs b/third_party/rust/wgpu-hal/src/auxil/renderdoc.rs
new file mode 100644
index 0000000000..b2e9242a89
--- /dev/null
+++ b/third_party/rust/wgpu-hal/src/auxil/renderdoc.rs
@@ -0,0 +1,141 @@
+//! RenderDoc integration - <https://renderdoc.org/>
+
+use std::{ffi, os, ptr};
+
+/// The dynamically loaded RenderDoc API function table
+#[repr(C)]
+#[derive(Debug)]
+pub struct RenderDocApi {
+ api: renderdoc_sys::RENDERDOC_API_1_4_1,
+ lib: libloading::Library,
+}
+
+unsafe impl Send for RenderDocApi {}
+unsafe impl Sync for RenderDocApi {}
+
+/// RenderDoc API type
+#[derive(Debug)]
+pub enum RenderDoc {
+ /// RenderDoc functionality is available
+ Available {
+ /// RenderDoc API with function pointers
+ api: RenderDocApi,
+ },
+ /// RenderDoc functionality is _not_ available
+ NotAvailable {
+ /// A description why renderdoc functionality is not available
+ reason: String,
+ },
+}
+
+// TODO: replace with libloading API once supported
+#[cfg(unix)]
+const RTLD_NOLOAD: i32 = 0x4;
+
+impl RenderDoc {
+ pub unsafe fn new() -> Self {
+ type GetApiFn = unsafe extern "C" fn(version: u32, out: *mut *mut ffi::c_void) -> i32;
+
+ #[cfg(windows)]
+ let renderdoc_filename = "renderdoc.dll";
+ #[cfg(all(unix, not(target_os = "android")))]
+ let renderdoc_filename = "librenderdoc.so";
+ #[cfg(target_os = "android")]
+ let renderdoc_filename = "libVkLayer_GLES_RenderDoc.so";
+
+ #[cfg(unix)]
+ let renderdoc_result: Result<libloading::Library, libloading::Error> = unsafe {
+ libloading::os::unix::Library::open(
+ Some(renderdoc_filename),
+ libloading::os::unix::RTLD_NOW | RTLD_NOLOAD,
+ )
+ }
+ .map(|lib| lib.into());
+
+ #[cfg(windows)]
+ let renderdoc_result: Result<libloading::Library, libloading::Error> =
+ libloading::os::windows::Library::open_already_loaded(renderdoc_filename)
+ .map(|lib| lib.into());
+
+ let renderdoc_lib = match renderdoc_result {
+ Ok(lib) => lib,
+ Err(e) => {
+ return RenderDoc::NotAvailable {
+ reason: format!(
+ "Unable to load renderdoc library '{}': {:?}",
+ renderdoc_filename, e
+ ),
+ }
+ }
+ };
+
+ let get_api: libloading::Symbol<GetApiFn> =
+ match unsafe { renderdoc_lib.get(b"RENDERDOC_GetAPI\0") } {
+ Ok(api) => api,
+ Err(e) => {
+ return RenderDoc::NotAvailable {
+ reason: format!(
+ "Unable to get RENDERDOC_GetAPI from renderdoc library '{}': {:?}",
+ renderdoc_filename, e
+ ),
+ }
+ }
+ };
+ let mut obj = ptr::null_mut();
+ match unsafe { get_api(10401, &mut obj) } {
+ 1 => RenderDoc::Available {
+ api: RenderDocApi {
+ api: unsafe { *(obj as *mut renderdoc_sys::RENDERDOC_API_1_4_1) },
+ lib: renderdoc_lib,
+ },
+ },
+ return_value => RenderDoc::NotAvailable {
+ reason: format!(
+ "Unable to get API from renderdoc library '{}': {}",
+ renderdoc_filename, return_value
+ ),
+ },
+ }
+ }
+}
+
+impl Default for RenderDoc {
+ fn default() -> Self {
+ if !cfg!(debug_assertions) {
+ return RenderDoc::NotAvailable {
+ reason: "RenderDoc support is only enabled with 'debug_assertions'".into(),
+ };
+ }
+ unsafe { Self::new() }
+ }
+}
+/// A implementation specific handle
+pub type Handle = *mut os::raw::c_void;
+
+impl RenderDoc {
+ /// Start a RenderDoc frame capture
+ pub unsafe fn start_frame_capture(&self, device_handle: Handle, window_handle: Handle) -> bool {
+ match *self {
+ Self::Available { api: ref entry } => {
+ unsafe { entry.api.StartFrameCapture.unwrap()(device_handle, window_handle) };
+ true
+ }
+ Self::NotAvailable { ref reason } => {
+ log::warn!("Could not start RenderDoc frame capture: {}", reason);
+ false
+ }
+ }
+ }
+
+ /// End a RenderDoc frame capture
+ pub unsafe fn end_frame_capture(&self, device_handle: Handle, window_handle: Handle) {
+ match *self {
+ Self::Available { api: ref entry } => {
+ unsafe { entry.api.EndFrameCapture.unwrap()(device_handle, window_handle) };
+ }
+ Self::NotAvailable { ref reason } => {
+ log::warn!("Could not end RenderDoc frame capture: {}", reason)
+ }
+ };
+ }
+}