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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
use crate::api::icd::CLResult;
use crate::api::icd::DISPATCH;
use crate::core::device::*;
use crate::core::version::*;
use mesa_rust_gen::*;
use rusticl_opencl_gen::*;
use std::env;
use std::sync::Arc;
use std::sync::Once;
#[repr(C)]
pub struct Platform {
dispatch: &'static cl_icd_dispatch,
pub extensions: [cl_name_version; 2],
pub devs: Vec<Arc<Device>>,
}
pub struct PlatformDebug {
pub program: bool,
}
pub struct PlatformFeatures {
pub fp64: bool,
}
static PLATFORM_ENV_ONCE: Once = Once::new();
static PLATFORM_ONCE: Once = Once::new();
static mut PLATFORM: Platform = Platform {
dispatch: &DISPATCH,
extensions: [
mk_cl_version_ext(1, 0, 0, "cl_khr_icd"),
mk_cl_version_ext(1, 0, 0, "cl_khr_il_program"),
],
devs: Vec::new(),
};
static mut PLATFORM_DBG: PlatformDebug = PlatformDebug { program: false };
static mut PLATFORM_FEATURES: PlatformFeatures = PlatformFeatures { fp64: false };
fn load_env() {
let debug = unsafe { &mut PLATFORM_DBG };
if let Ok(debug_flags) = env::var("RUSTICL_DEBUG") {
for flag in debug_flags.split(',') {
match flag {
"program" => debug.program = true,
_ => eprintln!("Unknown RUSTICL_DEBUG flag found: {}", flag),
}
}
}
let features = unsafe { &mut PLATFORM_FEATURES };
if let Ok(feature_flags) = env::var("RUSTICL_FEATURES") {
for flag in feature_flags.split(',') {
match flag {
"fp64" => features.fp64 = true,
_ => eprintln!("Unknown RUSTICL_FEATURES flag found: {}", flag),
}
}
}
}
impl Platform {
pub fn as_ptr(&self) -> cl_platform_id {
(self as *const Self) as cl_platform_id
}
pub fn get() -> &'static Self {
debug_assert!(PLATFORM_ONCE.is_completed());
// SAFETY: no mut references exist at this point
unsafe { &PLATFORM }
}
pub fn dbg() -> &'static PlatformDebug {
debug_assert!(PLATFORM_ENV_ONCE.is_completed());
unsafe { &PLATFORM_DBG }
}
pub fn features() -> &'static PlatformFeatures {
debug_assert!(PLATFORM_ENV_ONCE.is_completed());
unsafe { &PLATFORM_FEATURES }
}
fn init(&mut self) {
unsafe {
glsl_type_singleton_init_or_ref();
}
self.devs.extend(Device::all());
}
pub fn init_once() {
PLATFORM_ENV_ONCE.call_once(load_env);
// SAFETY: no concurrent static mut access due to std::Once
PLATFORM_ONCE.call_once(|| unsafe { PLATFORM.init() });
}
}
impl Drop for Platform {
fn drop(&mut self) {
unsafe {
glsl_type_singleton_decref();
}
}
}
pub trait GetPlatformRef {
fn get_ref(&self) -> CLResult<&'static Platform>;
}
impl GetPlatformRef for cl_platform_id {
fn get_ref(&self) -> CLResult<&'static Platform> {
if !self.is_null() && *self == Platform::get().as_ptr() {
Ok(Platform::get())
} else {
Err(CL_INVALID_PLATFORM)
}
}
}
|