1#![warn(
2 trivial_casts,
3 trivial_numeric_casts,
4 unused_extern_crates,
5 unused_import_braces,
6 unused_qualifications
7)]
8
9#[repr(C)]
13#[derive(Debug)]
14pub struct RenderDocApi {
15 api: renderdoc_sys::RENDERDOC_API_1_4_1,
16 lib: libloading::Library,
17}
18
19unsafe impl Send for RenderDocApi {}
20
21unsafe impl Sync for RenderDocApi {}
22
23#[derive(Debug)]
25pub enum RenderDoc {
26 Available {
28 api: RenderDocApi,
30 },
31 NotAvailable {
33 reason: String,
35 },
36}
37
38impl RenderDoc {
39 pub unsafe fn new() -> Self {
40 type GetApiFn = unsafe extern "C" fn(version: u32, out: *mut *mut std::ffi::c_void) -> i32;
41
42 #[cfg(windows)]
43 let renderdoc_filename = "renderdoc.dll";
44 #[cfg(all(unix, not(target_os = "android")))]
45 let renderdoc_filename = "librenderdoc.so";
46 #[cfg(target_os = "android")]
47 let renderdoc_filename = "libVkLayer_GLES_RenderDoc.so";
48
49 let renderdoc_lib = match libloading::Library::new(renderdoc_filename) {
50 Ok(lib) => lib,
51 Err(e) => {
52 return RenderDoc::NotAvailable {
53 reason: format!(
54 "Unable to load renderdoc library '{}': {:?}",
55 renderdoc_filename, e
56 ),
57 }
58 }
59 };
60
61 let get_api: libloading::Symbol<GetApiFn> = match renderdoc_lib.get(b"RENDERDOC_GetAPI\0") {
62 Ok(api) => api,
63 Err(e) => {
64 return RenderDoc::NotAvailable {
65 reason: format!(
66 "Unable to get RENDERDOC_GetAPI from renderdoc library '{}': {:?}",
67 renderdoc_filename, e
68 ),
69 }
70 }
71 };
72 let mut obj = std::ptr::null_mut();
73 match get_api(10401, &mut obj) {
74 1 => RenderDoc::Available {
75 api: RenderDocApi {
76 api: *(obj as *mut renderdoc_sys::RENDERDOC_API_1_4_1),
77 lib: renderdoc_lib,
78 },
79 },
80 return_value => RenderDoc::NotAvailable {
81 reason: format!(
82 "Unable to get API from renderdoc library '{}': {}",
83 renderdoc_filename, return_value
84 ),
85 },
86 }
87 }
88}
89
90impl Default for RenderDoc {
91 fn default() -> Self {
92 if !cfg!(debug_assertions) {
93 return RenderDoc::NotAvailable {
94 reason: "RenderDoc support is only enabled with 'debug_assertions'".into(),
95 };
96 }
97 unsafe { Self::new() }
98 }
99}
100pub type Handle = *mut ::std::os::raw::c_void;
102
103impl RenderDoc {
104 pub unsafe fn start_frame_capture(&self, device_handle: Handle, window_handle: Handle) {
106 match self {
107 Self::Available { api: ref entry } => {
108 entry.api.StartFrameCapture.unwrap()(device_handle, window_handle);
109 }
110 Self::NotAvailable { ref reason } => {
111 log::warn!("Could not start RenderDoc frame capture: {}", reason)
112 }
113 };
114 }
115
116 pub unsafe fn end_frame_capture(&self, device_handle: Handle, window_handle: Handle) {
118 match self {
119 Self::Available { api: ref entry } => {
120 entry.api.EndFrameCapture.unwrap()(device_handle, window_handle);
121 }
122 Self::NotAvailable { ref reason } => {
123 log::warn!("Could not end RenderDoc frame capture: {}", reason)
124 }
125 };
126 }
127}