Skip to content

Commit 9252ae6

Browse files
committed
Fix loading of RenderDoc library
It turns out this crate has been loading the RenderDoc API incorrectly: > To do this you'll use your platforms dynamic library functions to see > if the library is open already - e.g. `GetModuleHandle` on Windows, or > or `dlopen` with the `RTLD_NOW | RTLD_NOLOAD` flags if available on > *nix systems. On most platforms you can just search for the module > name - `renderdoc.dll` on Windows, or `librenderdoc.so` on Linux, or > `libVkLayer_GLES_RenderDoc.so` on Android should be sufficient here, > so you don’t need to know the path to where RenderDoc is running from. > This will vary by platform however so consult your platform’s OS > documentation. Then you can use `GetProcAddress` or `dlsym` to fetch > the `RENDERDOC_GetAPI` function using the typedef above. This was reported long ago as an issue, and I'm addressing this now with this commit. It does change the runtime behavior of the library, though: the application no longer attempts to load RenderDoc into memory if not injected from the outside, so `RenderDoc::new()` will now return `Err` when previously it would have succeeded.
1 parent 5384f04 commit 9252ae6

File tree

2 files changed

+30
-31
lines changed

2 files changed

+30
-31
lines changed

examples/triangle.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
3838
.await
3939
.expect("Failed to create device");
4040

41-
let mut rd: RenderDoc<V110> = RenderDoc::new().unwrap();
41+
let mut rd: RenderDoc<V110> = RenderDoc::new().expect("RenderDoc is not running");
4242
rd.set_focus_toggle_keys(&[InputButton::F]);
4343
rd.set_capture_keys(&[InputButton::C]);
4444

src/version.rs

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,14 @@
11
//! Entry points for the RenderDoc API.
22
3-
use std::os::raw::c_void;
4-
use std::path::Path;
3+
use std::ffi::c_void;
4+
use std::ptr;
55

66
use libloading::{Library, Symbol};
77
use once_cell::sync::OnceCell;
88
use renderdoc_sys::RENDERDOC_API_1_4_1;
99

1010
use crate::error::Error;
1111

12-
static RD_LIB: OnceCell<Library> = OnceCell::new();
13-
14-
#[cfg(windows)]
15-
fn get_path() -> &'static Path {
16-
Path::new("renderdoc.dll")
17-
}
18-
19-
#[cfg(all(unix, not(target_os = "android")))]
20-
fn get_path() -> &'static Path {
21-
Path::new("librenderdoc.so")
22-
}
23-
24-
#[cfg(target_os = "android")]
25-
fn get_path() -> &'static Path {
26-
Path::new("libVkLayer_GLES_RenderDoc.so")
27-
}
28-
2912
/// Entry point for the RenderDoc API.
3013
pub type Entry = RENDERDOC_API_1_4_1;
3114

@@ -55,13 +38,6 @@ pub enum VersionCode {
5538
V141 = 10401,
5639
}
5740

58-
/// Initializes a new instance of the RenderDoc API.
59-
///
60-
/// # Safety
61-
///
62-
/// This function is not thread-safe and should not be called on multiple threads at once.
63-
type GetApiFn = unsafe extern "C" fn(ver: VersionCode, out: *mut *mut c_void) -> i32;
64-
6541
/// Entry point into the RenderDoc API.
6642
pub trait Version {
6743
/// Minimum compatible version number.
@@ -73,18 +49,41 @@ pub trait Version {
7349
///
7450
/// This function is not thread-safe and should not be called on multiple threads at once.
7551
fn load() -> Result<*mut Entry, Error> {
76-
use std::ptr;
52+
static LIBRARY: OnceCell<Library> = OnceCell::new();
53+
54+
type GetApiFn = unsafe extern "C" fn(ver: u32, out: *mut *mut c_void) -> i32;
55+
56+
#[cfg(windows)]
57+
let lib_path = "renderdoc.dll";
58+
#[cfg(all(unix, not(target_os = "android")))]
59+
let lib_path = "librenderdoc.so";
60+
#[cfg(target_os = "android")]
61+
let lib_path = "libVkLayer_GLES_RenderDoc.so";
7762

7863
unsafe {
79-
let lib = RD_LIB
80-
.get_or_try_init(|| Library::new(get_path()))
64+
#[cfg(unix)]
65+
let lib = LIBRARY
66+
.get_or_try_init(|| {
67+
// TODO: Use constant from `libloading`, once added upstream.
68+
const RTLD_NOLOAD: i32 = 0x4;
69+
70+
let flags = libloading::os::unix::RTLD_NOW | RTLD_NOLOAD;
71+
libloading::os::unix::Library::open(Some(lib_path), flags).map(Into::into)
72+
})
73+
.map_err(Error::library)?;
74+
75+
#[cfg(windows)]
76+
let lib = LIBRARY
77+
.get_or_try_init(|| {
78+
libloading::os::windows::Library::open_already_loaded(lib_path).map(Into::into)
79+
})
8180
.map_err(Error::library)?;
8281

8382
let get_api: Symbol<GetApiFn> =
8483
lib.get(b"RENDERDOC_GetAPI\0").map_err(Error::symbol)?;
8584

8685
let mut obj = ptr::null_mut();
87-
match get_api(Self::VERSION, &mut obj) {
86+
match get_api(Self::VERSION as u32, &mut obj) {
8887
1 => Ok(obj as *mut Entry),
8988
_ => Err(Error::no_compatible_api()),
9089
}

0 commit comments

Comments
 (0)