1 use crate::api::icd::CLResult;
2 use crate::api::util::*;
3 use crate::core::platform::*;
4 use crate::core::version::*;
5
6 use mesa_rust_util::ptr::*;
7 use rusticl_opencl_gen::*;
8 use rusticl_proc_macros::cl_entrypoint;
9 use rusticl_proc_macros::cl_info_entrypoint;
10
11 use std::mem::MaybeUninit;
12
13 #[cl_info_entrypoint(clGetPlatformInfo)]
14 impl CLInfo<cl_platform_info> for cl_platform_id {
query(&self, q: cl_platform_info, _: &[u8]) -> CLResult<Vec<MaybeUninit<u8>>>15 fn query(&self, q: cl_platform_info, _: &[u8]) -> CLResult<Vec<MaybeUninit<u8>>> {
16 self.get_ref()?;
17 Ok(match q {
18 // TODO spirv
19 CL_PLATFORM_EXTENSIONS => cl_prop(PLATFORM_EXTENSION_STR),
20 CL_PLATFORM_EXTENSIONS_WITH_VERSION => {
21 cl_prop::<Vec<cl_name_version>>(PLATFORM_EXTENSIONS.to_vec())
22 }
23 CL_PLATFORM_HOST_TIMER_RESOLUTION => cl_prop::<cl_ulong>(1),
24 CL_PLATFORM_ICD_SUFFIX_KHR => cl_prop("MESA"),
25 CL_PLATFORM_NAME => cl_prop("rusticl"),
26 CL_PLATFORM_NUMERIC_VERSION => cl_prop::<cl_version>(CLVersion::Cl3_0 as u32),
27 CL_PLATFORM_PROFILE => cl_prop("FULL_PROFILE"),
28 CL_PLATFORM_VENDOR => cl_prop("Mesa/X.org"),
29 // OpenCL<space><major_version.minor_version><space><platform-specific information>
30 CL_PLATFORM_VERSION => cl_prop("OpenCL 3.0 "),
31 // CL_INVALID_VALUE if param_name is not one of the supported values
32 _ => return Err(CL_INVALID_VALUE),
33 })
34 }
35 }
36
37 #[cl_entrypoint(clGetPlatformIDs)]
get_platform_ids( num_entries: cl_uint, platforms: *mut cl_platform_id, num_platforms: *mut cl_uint, ) -> CLResult<()>38 fn get_platform_ids(
39 num_entries: cl_uint,
40 platforms: *mut cl_platform_id,
41 num_platforms: *mut cl_uint,
42 ) -> CLResult<()> {
43 // CL_INVALID_VALUE if num_entries is equal to zero and platforms is not NULL
44 if num_entries == 0 && !platforms.is_null() {
45 return Err(CL_INVALID_VALUE);
46 }
47
48 // or if both num_platforms and platforms are NULL."
49 if num_platforms.is_null() && platforms.is_null() {
50 return Err(CL_INVALID_VALUE);
51 }
52
53 // run initialization code once
54 Platform::init_once();
55
56 // platforms returns a list of OpenCL platforms available for access through the Khronos ICD Loader.
57 // The cl_platform_id values returned in platforms are ICD compatible and can be used to identify a
58 // specific OpenCL platform. If the platforms argument is NULL, then this argument is ignored. The
59 // number of OpenCL platforms returned is the minimum of the value specified by num_entries or the
60 // number of OpenCL platforms available.
61 platforms.write_checked(Platform::get().as_ptr());
62
63 // num_platforms returns the number of OpenCL platforms available. If num_platforms is NULL, then
64 // this argument is ignored.
65 num_platforms.write_checked(1);
66
67 Ok(())
68 }
69
70 #[cl_entrypoint(clUnloadPlatformCompiler)]
unload_platform_compiler(platform: cl_platform_id) -> CLResult<()>71 fn unload_platform_compiler(platform: cl_platform_id) -> CLResult<()> {
72 platform.get_ref()?;
73 // TODO unload the compiler
74 Ok(())
75 }
76
77 #[test]
test_get_platform_info()78 fn test_get_platform_info() {
79 let mut s: usize = 0;
80 let mut r = get_platform_info(
81 ptr::null(),
82 CL_PLATFORM_EXTENSIONS,
83 0,
84 ptr::null_mut(),
85 &mut s,
86 );
87 assert!(r.is_ok());
88 assert!(s > 0);
89
90 let mut v: Vec<u8> = vec![0; s];
91 r = get_platform_info(
92 ptr::null(),
93 CL_PLATFORM_EXTENSIONS,
94 s,
95 v.as_mut_ptr().cast(),
96 &mut s,
97 );
98
99 assert!(r.is_ok());
100 assert_eq!(s, v.len());
101 assert!(!v[0..s - 2].contains(&0));
102 assert_eq!(v[s - 1], 0);
103 }
104