1use std::fmt::{Display, Formatter};
2use std::ops::{BitAnd, BitOr, Not};
3use std::str::FromStr;
4
5pub type PlatformId = usize;
7
8pub type DeviceId = usize;
10
11#[derive(Eq, PartialEq, Copy, Clone)]
13#[cfg_attr(test, derive(Debug))]
14#[repr(u32)]
15pub enum PlatformInfo {
16 Profile = 0x0900,
18 Version = 0x0901,
20 Name = 0x0902,
22 Vendor = 0x0903,
24 Extensions = 0x0904,
26}
27
28#[derive(Eq, PartialEq, Copy, Clone)]
30#[cfg_attr(test, derive(Debug))]
31#[repr(transparent)]
32pub struct DeviceType(u64);
33
34impl DeviceType {
35 pub const DEFAULT: Self = DeviceType(1 << 0);
37 pub const CPU: Self = DeviceType(1 << 1);
39 pub const GPU: Self = DeviceType(1 << 2);
41 pub const ACCELERATOR: Self = DeviceType(1 << 3);
43 pub const CUSTOM: Self = DeviceType(1 << 4);
45 pub const ALL: Self = DeviceType(0xFFFFFFFF);
47
48 pub fn raw(&self) -> u64 {
50 unsafe { std::mem::transmute_copy(self) }
51 }
52}
53
54impl BitOr for DeviceType {
55 type Output = Self;
56
57 fn bitor(self, rhs: Self) -> Self::Output {
58 Self(self.0 | rhs.0)
59 }
60}
61
62impl BitAnd for DeviceType {
63 type Output = Self;
64
65 fn bitand(self, rhs: Self) -> Self::Output {
66 Self(self.0 & rhs.0)
67 }
68}
69
70impl Not for DeviceType {
71 type Output = Self;
72
73 fn not(self) -> Self::Output {
74 Self((!self.0) & DeviceType::ALL.0)
75 }
76}
77
78#[derive(Eq, PartialEq, Copy, Clone)]
80#[cfg_attr(test, derive(Debug))]
81pub enum Profile {
82 Full,
84
85 Embedded,
88}
89
90impl TryFrom<String> for Profile {
91 type Error = String;
92
93 fn try_from(value: String) -> Result<Self, Self::Error> {
94 match value.as_str() {
95 "FULL_PROFILE" => Ok(Profile::Full),
96 "EMBEDDED_PROFILE" => Ok(Profile::Embedded),
97 _ => Err(value),
98 }
99 }
100}
101
102impl Display for Profile {
103 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
104 match *self {
105 Profile::Full => write!(f, "FULL_PROFILE"),
106 Profile::Embedded => write!(f, "EMBEDDED_PROFILE"),
107 }
108 }
109}
110
111#[derive(Clone, Eq, PartialEq)]
113#[cfg_attr(test, derive(Debug))]
114pub struct Version {
115 major: u8,
117
118 minor: u8,
120
121 extra: Option<String>,
123}
124
125impl Version {
126 pub fn major(&self) -> u8 {
128 self.major
129 }
130
131 pub fn minor(&self) -> u8 {
133 self.minor
134 }
135
136 pub fn extra(&self) -> &Option<String> {
138 &self.extra
139 }
140}
141
142impl TryFrom<String> for Version {
143 type Error = String;
144
145 fn try_from(value: String) -> Result<Self, Self::Error> {
146 let parts: Vec<&str> = value.splitn(3, " ").collect();
147 if !(2..=3).contains(&parts.len()) || parts[0] != "OpenCL" {
148 return Err(value);
149 }
150
151 let (major_str, minor_str) = parts[1].split_once('.').ok_or_else(|| value.clone())?;
152 let major = u8::from_str(major_str).or_else(|_| Err(value.clone()))?;
153 let minor = u8::from_str(minor_str).or_else(|_| Err(value.clone()))?;
154
155 let extra = if parts.len() == 3 {
156 Some(parts[2].to_string())
157 } else {
158 None
159 };
160
161 Ok(Version { major, minor, extra })
162 }
163}
164
165impl Display for Version {
166 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
167 match self.extra() {
168 Some(extra) => write!(f, "OpenCL {}.{} {}", self.major, self.minor, extra),
169 None => write!(f, "OpenCL {}.{}", self.major, self.minor),
170 }
171 }
172}