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}