Skip to main content

adlx/
system.rs

1use std::mem::MaybeUninit;
2
3use super::{
4    ffi,
5    gpu_list::GpuList,
6    interface::{Interface, InterfaceImpl},
7    performance_monitoring_services::PerformanceMonitoringServices,
8    result::{Error, Result},
9};
10
11/// <https://gpuopen.com/manuals/adlx/adlx-_d_o_x__i_a_d_l_x_system/>
12///
13/// [`System`] is a singleton interface.  It looks similar to but is not compatible with
14/// [`Interface`].
15#[derive(Debug)]
16#[repr(transparent)]
17#[doc(alias = "IADLXSystem")]
18pub struct System(*mut ffi::IADLXSystem);
19
20unsafe impl Send for System {}
21unsafe impl Sync for System {}
22
23impl System {
24    /// Creates an [`Interface`] by taking ownership of the `raw` COM/ADLX interface pointer.
25    ///
26    /// # Safety
27    ///
28    /// The `raw` pointer must be owned by the caller and represent a valid [`ffi::IADLXSystem`]
29    /// pointer. In other words, it must point to a vtable beginning with the
30    /// [`ffi::IADLXSystemVtbl`] function pointers.
31    pub(crate) unsafe fn from_raw(raw: *mut ffi::IADLXSystem) -> Self {
32        Self(raw)
33    }
34
35    fn vtable(&self) -> &ffi::IADLXSystemVtbl {
36        unsafe { &*(*self.0).pVtbl }
37    }
38
39    /// <https://gpuopen.com/manuals/adlx/adlx-_d_o_x__i_a_d_l_x_system__hybrid_graphics_type/>
40    #[doc(alias = "GetHybridGraphicsType")]
41    pub fn hybrid_graphics_type(&self) -> Result<ffi::ADLX_HG_TYPE> {
42        let mut type_ = MaybeUninit::uninit();
43        let result =
44            unsafe { (self.vtable().GetHybridGraphicsType.unwrap())(self.0, type_.as_mut_ptr()) };
45        Error::from_result_with_assume_init_on_success(result, type_)
46    }
47    /// <https://gpuopen.com/manuals/adlx/adlx-_d_o_x__i_a_d_l_x_system__get_g_p_us/>
48    #[doc(alias = "GetGPUs")]
49    pub fn gpus(&self) -> Result<GpuList> {
50        let mut gpu_list = MaybeUninit::uninit();
51        let result = unsafe { (self.vtable().GetGPUs.unwrap())(self.0, gpu_list.as_mut_ptr()) };
52        Error::from_result_with_assume_init_on_success(result, gpu_list)
53            .map(|gpu_list| unsafe { GpuList::from_raw(gpu_list) })
54    }
55    /// <https://gpuopen.com/manuals/adlx/adlx-_d_o_x__i_a_d_l_x_system__query_interface/>
56    #[doc(alias = "QueryInterface")]
57    pub fn cast<I: Interface>(&self) -> Result<I> {
58        let interface_name = I::IID
59            // TODO: Use windows-rs' helpers to create static wchars?
60            .encode_utf16()
61            .chain(std::iter::once(0u16))
62            .collect::<Vec<_>>();
63        let mut interface = std::mem::MaybeUninit::uninit();
64        let result = unsafe {
65            (self.vtable().QueryInterface.unwrap())(
66                self.0,
67                interface_name.as_ptr(),
68                interface.as_mut_ptr(),
69            )
70        };
71        Error::from_result(result).map(|()| unsafe { I::from_raw(interface.assume_init().cast()) })
72    }
73    // #[doc(alias = "GetDisplaysServices")]
74    // pub fn GetDisplaysServices(&self) -> Result<()> {
75    //     let result = unsafe { (self.vtable().GetDisplaysServices.unwrap())(self.0) };
76    //     Error::from_result(result)?;
77
78    //     Ok(())
79    // }
80    // #[doc(alias = "GetDesktopsServices")]
81    // pub fn GetDesktopsServices(&self) -> Result<()> {
82    //     let result = unsafe { (self.vtable().GetDesktopsServices.unwrap())(self.0) };
83    //     Error::from_result(result)?;
84
85    //     Ok(())
86    // }
87    // #[doc(alias = "GetGPUsChangedHandling")]
88    // pub fn GetGPUsChangedHandling(&self) -> Result<()> {
89    //     let result = unsafe { (self.vtable().GetGPUsChangedHandling.unwrap())(self.0) };
90    //     Error::from_result(result)?;
91
92    //     Ok(())
93    // }
94    // #[doc(alias = "EnableLog")]
95    // pub fn EnableLog(&self) -> Result<()> {
96    //     let result = unsafe { (self.vtable().EnableLog.unwrap())(self.0) };
97    //     Error::from_result(result)?;
98
99    //     Ok(())
100    // }
101    // #[doc(alias = "Get3DSettingsServices")]
102    // pub fn Get3DSettingsServices(&self) -> Result<()> {
103    //     let result = unsafe { (self.vtable().Get3DSettingsServices.unwrap())(self.0) };
104    //     Error::from_result(result)?;
105
106    //     Ok(())
107    // }
108    // #[doc(alias = "GetGPUTuningServices")]
109    // pub fn GetGPUTuningServices(&self) -> Result<()> {
110    //     let result = unsafe { (self.vtable().GetGPUTuningServices.unwrap())(self.0) };
111    //     Error::from_result(result)?;
112
113    //     Ok(())
114    // }
115    #[doc(alias = "GetPerformanceMonitoringServices")]
116    pub fn performance_monitoring_services(&self) -> Result<PerformanceMonitoringServices> {
117        let mut services = MaybeUninit::uninit();
118        let result = unsafe {
119            (self.vtable().GetPerformanceMonitoringServices.unwrap())(self.0, services.as_mut_ptr())
120        };
121        Error::from_result_with_assume_init_on_success(result, services)
122            .map(|services| unsafe { PerformanceMonitoringServices::from_raw(services) })
123    }
124    // #[doc(alias = "TotalSystemRAM")]
125    // pub fn TotalSystemRAM(&self) -> Result<()> {
126    //     let result = unsafe { (self.vtable().TotalSystemRAM.unwrap())(self.0) };
127    //     Error::from_result(result)?;
128
129    //     Ok(())
130    // }
131    // #[doc(alias = "GetI2C")]
132    // pub fn GetI2C(&self) -> Result<()> {
133    //     let result = unsafe { (self.vtable().GetI2C.unwrap())(self.0) };
134    //     Error::from_result(result)?;
135
136    //     Ok(())
137    // }
138}
139
140/// <https://gpuopen.com/manuals/adlx/adlx-_d_o_x__i_a_d_l_x_system1/>
141#[derive(Clone, Debug)]
142#[repr(transparent)]
143#[doc(alias = "IADLXSystem1")]
144pub struct System1(InterfaceImpl);
145
146unsafe impl Interface for System1 {
147    type Impl = ffi::IADLXSystem1;
148    type Vtable = ffi::IADLXSystem1Vtbl;
149    const IID: &'static str = "IADLXSystem1";
150}
151
152impl System1 {
153    // /// <https://gpuopen.com/manuals/adlx/adlx-_d_o_x__i_a_d_l_x_system1__get_power_tuning_services/>
154    // #[doc(alias = "GetPowerTuningServices")]
155    // pub fn power_tuning_services(&self) -> Result<PowerTuningServices> {
156    //     let mut ret = MaybeUninit::uninit();
157    //     let result = unsafe {
158    //         (self.vtable().GetPowerTuningServices.unwrap())(self.imp(), ret.as_mut_ptr())
159    //     };
160    //     let ret = Error::from_result_with_assume_init_on_success(result, ret)?;
161    //     Ok(PowerTuningServices::from_raw(ret))
162    // }
163}