1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//! API versioning.

use entry::{EntryV100, EntryV110};

/// Available versions of the RenderDoc API.
#[repr(u32)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum Version {
    /// Version 1.0.0.
    V100 = 10000,
    /// Version 1.0.1.
    V101 = 10001,
    /// Version 1.0.2.
    V102 = 10002,
    /// Version 1.1.0.
    V110 = 10100,
    /// Version 1.1.1.
    V111 = 10101,
}

/// Initializes a new instance of the RenderDoc API.
///
/// # Safety
///
/// This function is not thread-safe and should not be called on multiple
/// threads at once.
type GetApiFn<T> = unsafe extern "C" fn(ver: Version, out: *mut *mut T) -> i32;

/// Entry point into the RenderDoc API.
pub trait ApiVersion {
    /// Minimum compatible version number.
    const VERSION: Version;

    /// Entry point struct.
    type Entry: Clone;

    /// Initializes a new instance of the RenderDoc API.
    ///
    /// # Safety
    ///
    /// This function is not thread-safe and should not be called on multiple
    /// threads at once.
    fn load() -> Result<Self::Entry, String> {
        use std::{mem, ptr};

        let api = unsafe {
            let get_api = match *super::RD_LIB {
                Ok(ref lib) => {
                    let f = lib.symbol::<()>("RENDERDOC_GetAPI")?;
                    Ok(mem::transmute::<_, GetApiFn<Self::Entry>>(f))
                }
                Err(ref err) => Err(err.to_string()),
            }?;

            let mut obj = ptr::null_mut();
            match get_api(Self::VERSION, &mut obj) {
                1 => ptr::read(obj),
                _ => Err("Compatible API version not available.")?,
            }
        };

        Ok(api)
    }
}

/// Requests a minimum version number of 1.0.0.
pub enum V100 {}

impl ApiVersion for V100 {
    const VERSION: Version = Version::V100;

    type Entry = EntryV100;
}

/// Requests a minimum version number of 1.1.0.
pub enum V110 {}

impl ApiVersion for V110 {
    const VERSION: Version = Version::V110;

    type Entry = EntryV110;
}