use std::os::raw::c_void;
use std::path::Path;
use libloading::{Library, Symbol};
use once_cell::sync::OnceCell;
use renderdoc_sys::RENDERDOC_API_1_4_1;
use crate::error::Error;
static RD_LIB: OnceCell<Library> = OnceCell::new();
#[cfg(windows)]
fn get_path() -> &'static Path {
Path::new("renderdoc.dll")
}
#[cfg(all(unix, not(target_os = "android")))]
fn get_path() -> &'static Path {
Path::new("librenderdoc.so")
}
#[cfg(target_os = "android")]
fn get_path() -> &'static Path {
Path::new("libVkLayer_GLES_RenderDoc.so")
}
pub type Entry = RENDERDOC_API_1_4_1;
#[repr(u32)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum VersionCode {
V100 = 10000,
V101 = 10001,
V102 = 10002,
V110 = 10100,
V111 = 10101,
V112 = 10102,
V120 = 10200,
V130 = 10300,
V140 = 10400,
V141 = 10401,
}
type GetApiFn = unsafe extern "C" fn(ver: VersionCode, out: *mut *mut c_void) -> i32;
pub trait Version {
const VERSION: VersionCode;
fn load() -> Result<*mut Entry, Error> {
use std::ptr;
unsafe {
let lib = RD_LIB
.get_or_try_init(|| Library::new(get_path()))
.map_err(Error::library)?;
let get_api: Symbol<GetApiFn> =
lib.get(b"RENDERDOC_GetAPI\0").map_err(Error::symbol)?;
let mut obj = ptr::null_mut();
match get_api(Self::VERSION, &mut obj) {
1 => Ok(obj as *mut Entry),
_ => Err(Error::no_compatible_api()),
}
}
}
}
pub trait HasPrevious: Version {
type Previous: Version;
}
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum V100 {}
impl Version for V100 {
const VERSION: VersionCode = VersionCode::V100;
}
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum V110 {}
impl Version for V110 {
const VERSION: VersionCode = VersionCode::V110;
}
impl HasPrevious for V110 {
type Previous = V100;
}
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum V111 {}
impl Version for V111 {
const VERSION: VersionCode = VersionCode::V111;
}
impl HasPrevious for V111 {
type Previous = V110;
}
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum V112 {}
impl Version for V112 {
const VERSION: VersionCode = VersionCode::V112;
}
impl HasPrevious for V112 {
type Previous = V111;
}
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum V120 {}
impl Version for V120 {
const VERSION: VersionCode = VersionCode::V120;
}
impl HasPrevious for V120 {
type Previous = V112;
}
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum V130 {}
impl Version for V130 {
const VERSION: VersionCode = VersionCode::V130;
}
impl HasPrevious for V130 {
type Previous = V120;
}
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum V140 {}
impl Version for V140 {
const VERSION: VersionCode = VersionCode::V140;
}
impl HasPrevious for V140 {
type Previous = V130;
}
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub enum V141 {}
impl Version for V141 {
const VERSION: VersionCode = VersionCode::V141;
}
impl HasPrevious for V141 {
type Previous = V140;
}