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