Skip to main content

adlx/
gpu_list.rs

1use std::{mem::MaybeUninit, ops::Deref};
2
3use super::{
4    ffi,
5    gpu::Gpu,
6    interface::Interface,
7    list::List,
8    result::{Error, Result},
9};
10
11/// <https://gpuopen.com/manuals/adlx/adlx-_d_o_x__i_a_d_l_x_g_p_u_list/>
12#[derive(Clone, Debug)]
13#[repr(transparent)]
14#[doc(alias = "IADLXGPUList")]
15pub struct GpuList(List);
16
17unsafe impl Interface for GpuList {
18    type Impl = ffi::IADLXGPUList;
19    type Vtable = ffi::IADLXGPUListVtbl;
20    const IID: &'static str = "IADLXGPUList";
21}
22
23impl Deref for GpuList {
24    type Target = List;
25
26    fn deref(&self) -> &Self::Target {
27        &self.0
28    }
29}
30
31impl GpuList {
32    /// <https://gpuopen.com/manuals/adlx/adlx-_d_o_x__i_a_d_l_x_g_p_u_list__at/>
33    #[doc(alias = "At_GPUList")]
34    pub fn at(&self, location: u32) -> Result<Gpu> {
35        let mut gpu = MaybeUninit::uninit();
36        let result = unsafe {
37            (self.vtable().At_GPUList.unwrap())(self.as_raw(), location, gpu.as_mut_ptr())
38        };
39        Error::from_result_with_assume_init_on_success(result, gpu)
40            .map(|gpu| unsafe { Gpu::from_raw(gpu) })
41    }
42    /// <https://gpuopen.com/manuals/adlx/adlx-_d_o_x__i_a_d_l_x_g_p_u_list__add__back/#doxid-d-o-x-i-a-d-l-x-g-p-u-list-add-back>
43    #[doc(alias = "Add_Back_GPUList")]
44    // TODO(Marijn): This API does not allow moves of derivatives, such as Gpu1.
45    pub fn add_back(&self, gpu: Gpu) -> Result<()> {
46        let result = unsafe {
47            // TODO: Assume ownership is consumed here?
48            (self.vtable().Add_Back_GPUList.unwrap())(self.as_raw(), gpu.into_raw())
49        };
50        Error::from_result(result)
51    }
52
53    pub fn iter(&self) -> GpuIterator {
54        GpuIterator { list: self, i: 0 }
55    }
56}
57
58pub struct GpuIterator<'a> {
59    list: &'a GpuList,
60    i: u32,
61}
62
63impl<'a> Iterator for GpuIterator<'a> {
64    type Item = Gpu;
65
66    fn next(&mut self) -> Option<Self::Item> {
67        if self.i < self.list.size() {
68            let gpu = self.list.at(self.i).unwrap();
69            self.i += 1;
70            Some(gpu)
71        } else {
72            None
73        }
74    }
75}
76
77impl ExactSizeIterator for GpuIterator<'_> {
78    fn len(&self) -> usize {
79        self.list.size() as usize
80    }
81}