1 //
2 // Copyright 2012 Francisco Jerez
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 // OTHER DEALINGS IN THE SOFTWARE.
21 //
22
23 #include <unordered_map>
24
25 #include "api/dispatch.hpp"
26 #include "api/util.hpp"
27 #include "core/platform.hpp"
28 #include "git_sha1.h"
29 #include "util/u_debug.h"
30
31 using namespace clover;
32
33 namespace {
34 platform _clover_platform;
35 }
36
37 CLOVER_API cl_int
clGetPlatformIDs(cl_uint num_entries,cl_platform_id * rd_platforms,cl_uint * rnum_platforms)38 clGetPlatformIDs(cl_uint num_entries, cl_platform_id *rd_platforms,
39 cl_uint *rnum_platforms) {
40 if ((!num_entries && rd_platforms) ||
41 (!rnum_platforms && !rd_platforms))
42 return CL_INVALID_VALUE;
43
44 if (rnum_platforms)
45 *rnum_platforms = 1;
46 if (rd_platforms)
47 *rd_platforms = desc(_clover_platform);
48
49 return CL_SUCCESS;
50 }
51
find_platform(cl_platform_id d_platform)52 platform &clover::find_platform(cl_platform_id d_platform)
53 {
54 /* this error is only added in CL2.0 */
55 if (d_platform != desc(_clover_platform))
56 throw error(CL_INVALID_PLATFORM);
57 return obj(d_platform);
58 }
59
60 cl_int
GetPlatformInfo(cl_platform_id d_platform,cl_platform_info param,size_t size,void * r_buf,size_t * r_size)61 clover::GetPlatformInfo(cl_platform_id d_platform, cl_platform_info param,
62 size_t size, void *r_buf, size_t *r_size) try {
63 property_buffer buf { r_buf, size, r_size };
64
65 auto &platform = find_platform(d_platform);
66
67 switch (param) {
68 case CL_PLATFORM_PROFILE:
69 buf.as_string() = "FULL_PROFILE";
70 break;
71
72 case CL_PLATFORM_VERSION: {
73 buf.as_string() = "OpenCL " + platform.platform_version_as_string() + " Mesa " PACKAGE_VERSION MESA_GIT_SHA1;
74 break;
75 }
76 case CL_PLATFORM_NAME:
77 buf.as_string() = "Clover";
78 break;
79
80 case CL_PLATFORM_VENDOR:
81 buf.as_string() = "Mesa";
82 break;
83
84 case CL_PLATFORM_EXTENSIONS:
85 buf.as_string() = platform.supported_extensions_as_string();
86 break;
87
88 case CL_PLATFORM_ICD_SUFFIX_KHR:
89 buf.as_string() = "MESA";
90 break;
91
92 case CL_PLATFORM_NUMERIC_VERSION: {
93 buf.as_scalar<cl_version>() = platform.platform_version();
94 break;
95 }
96
97 case CL_PLATFORM_EXTENSIONS_WITH_VERSION:
98 buf.as_vector<cl_name_version>() = platform.supported_extensions();
99 break;
100
101 case CL_PLATFORM_HOST_TIMER_RESOLUTION:
102 buf.as_scalar<cl_ulong>() = 0;
103 break;
104
105 default:
106 throw error(CL_INVALID_VALUE);
107 }
108
109 return CL_SUCCESS;
110
111 } catch (error &e) {
112 return e.get();
113 }
114
115 void *
GetExtensionFunctionAddressForPlatform(cl_platform_id d_platform,const char * p_name)116 clover::GetExtensionFunctionAddressForPlatform(cl_platform_id d_platform,
117 const char *p_name) try {
118 obj(d_platform);
119 return GetExtensionFunctionAddress(p_name);
120
121 } catch (error &) {
122 return NULL;
123 }
124
125 namespace {
126
127 cl_int
enqueueSVMFreeARM(cl_command_queue command_queue,cl_uint num_svm_pointers,void * svm_pointers[],void (CL_CALLBACK * pfn_free_func)(cl_command_queue queue,cl_uint num_svm_pointers,void * svm_pointers[],void * user_data),void * user_data,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event)128 enqueueSVMFreeARM(cl_command_queue command_queue,
129 cl_uint num_svm_pointers,
130 void *svm_pointers[],
131 void (CL_CALLBACK *pfn_free_func) (
132 cl_command_queue queue, cl_uint num_svm_pointers,
133 void *svm_pointers[], void *user_data),
134 void *user_data,
135 cl_uint num_events_in_wait_list,
136 const cl_event *event_wait_list,
137 cl_event *event) {
138
139 return EnqueueSVMFree(command_queue, num_svm_pointers, svm_pointers,
140 pfn_free_func, user_data, num_events_in_wait_list,
141 event_wait_list, event, CL_COMMAND_SVM_FREE_ARM);
142 }
143
144 cl_int
enqueueSVMMapARM(cl_command_queue command_queue,cl_bool blocking_map,cl_map_flags map_flags,void * svm_ptr,size_t size,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event)145 enqueueSVMMapARM(cl_command_queue command_queue,
146 cl_bool blocking_map,
147 cl_map_flags map_flags,
148 void *svm_ptr,
149 size_t size,
150 cl_uint num_events_in_wait_list,
151 const cl_event *event_wait_list,
152 cl_event *event) {
153
154 return EnqueueSVMMap(command_queue, blocking_map, map_flags, svm_ptr, size,
155 num_events_in_wait_list, event_wait_list, event,
156 CL_COMMAND_SVM_MAP_ARM);
157 }
158
159 cl_int
enqueueSVMMemcpyARM(cl_command_queue command_queue,cl_bool blocking_copy,void * dst_ptr,const void * src_ptr,size_t size,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event)160 enqueueSVMMemcpyARM(cl_command_queue command_queue,
161 cl_bool blocking_copy,
162 void *dst_ptr,
163 const void *src_ptr,
164 size_t size,
165 cl_uint num_events_in_wait_list,
166 const cl_event *event_wait_list,
167 cl_event *event) {
168
169 return EnqueueSVMMemcpy(command_queue, blocking_copy, dst_ptr, src_ptr,
170 size, num_events_in_wait_list, event_wait_list,
171 event, CL_COMMAND_SVM_MEMCPY_ARM);
172 }
173
174 cl_int
enqueueSVMMemFillARM(cl_command_queue command_queue,void * svm_ptr,const void * pattern,size_t pattern_size,size_t size,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event)175 enqueueSVMMemFillARM(cl_command_queue command_queue,
176 void *svm_ptr,
177 const void *pattern,
178 size_t pattern_size,
179 size_t size,
180 cl_uint num_events_in_wait_list,
181 const cl_event *event_wait_list,
182 cl_event *event) {
183
184 return EnqueueSVMMemFill(command_queue, svm_ptr, pattern, pattern_size,
185 size, num_events_in_wait_list, event_wait_list,
186 event, CL_COMMAND_SVM_MEMFILL_ARM);
187 }
188
189 cl_int
enqueueSVMUnmapARM(cl_command_queue command_queue,void * svm_ptr,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event)190 enqueueSVMUnmapARM(cl_command_queue command_queue,
191 void *svm_ptr,
192 cl_uint num_events_in_wait_list,
193 const cl_event *event_wait_list,
194 cl_event *event) {
195
196 return EnqueueSVMUnmap(command_queue, svm_ptr, num_events_in_wait_list,
197 event_wait_list, event, CL_COMMAND_SVM_UNMAP_ARM);
198 }
199
200 const std::unordered_map<std::string, void *>
201 ext_funcs = {
202 // cl_arm_shared_virtual_memory
203 { "clEnqueueSVMFreeARM", reinterpret_cast<void *>(enqueueSVMFreeARM) },
204 { "clEnqueueSVMMapARM", reinterpret_cast<void *>(enqueueSVMMapARM) },
205 { "clEnqueueSVMMemcpyARM", reinterpret_cast<void *>(enqueueSVMMemcpyARM) },
206 { "clEnqueueSVMMemFillARM", reinterpret_cast<void *>(enqueueSVMMemFillARM) },
207 { "clEnqueueSVMUnmapARM", reinterpret_cast<void *>(enqueueSVMUnmapARM) },
208 { "clSetKernelArgSVMPointerARM", reinterpret_cast<void *>(clSetKernelArgSVMPointer) },
209 { "clSetKernelExecInfoARM", reinterpret_cast<void *>(clSetKernelExecInfo) },
210 { "clSVMAllocARM", reinterpret_cast<void *>(clSVMAlloc) },
211 { "clSVMFreeARM", reinterpret_cast<void *>(clSVMFree) },
212
213 // cl_khr_icd
214 { "clIcdGetPlatformIDsKHR", reinterpret_cast<void *>(IcdGetPlatformIDsKHR) },
215
216 // cl_khr_il_program
217 { "clCreateProgramWithILKHR", reinterpret_cast<void *>(CreateProgramWithILKHR) },
218 };
219
220 } // anonymous namespace
221
222 void *
GetExtensionFunctionAddress(const char * p_name)223 clover::GetExtensionFunctionAddress(const char *p_name) try {
224 return ext_funcs.at(p_name);
225 } catch (...) {
226 return nullptr;
227 }
228
229 cl_int
IcdGetPlatformIDsKHR(cl_uint num_entries,cl_platform_id * rd_platforms,cl_uint * rnum_platforms)230 clover::IcdGetPlatformIDsKHR(cl_uint num_entries, cl_platform_id *rd_platforms,
231 cl_uint *rnum_platforms) {
232 return clGetPlatformIDs(num_entries, rd_platforms, rnum_platforms);
233 }
234
235 CLOVER_ICD_API cl_int
clGetPlatformInfo(cl_platform_id d_platform,cl_platform_info param,size_t size,void * r_buf,size_t * r_size)236 clGetPlatformInfo(cl_platform_id d_platform, cl_platform_info param,
237 size_t size, void *r_buf, size_t *r_size) {
238 return GetPlatformInfo(d_platform, param, size, r_buf, r_size);
239 }
240
241 CLOVER_ICD_API void *
clGetExtensionFunctionAddress(const char * p_name)242 clGetExtensionFunctionAddress(const char *p_name) {
243 return GetExtensionFunctionAddress(p_name);
244 }
245
246 CLOVER_ICD_API void *
clGetExtensionFunctionAddressForPlatform(cl_platform_id d_platform,const char * p_name)247 clGetExtensionFunctionAddressForPlatform(cl_platform_id d_platform,
248 const char *p_name) {
249 return GetExtensionFunctionAddressForPlatform(d_platform, p_name);
250 }
251
252 CLOVER_ICD_API cl_int
clIcdGetPlatformIDsKHR(cl_uint num_entries,cl_platform_id * rd_platforms,cl_uint * rnum_platforms)253 clIcdGetPlatformIDsKHR(cl_uint num_entries, cl_platform_id *rd_platforms,
254 cl_uint *rnum_platforms) {
255 return IcdGetPlatformIDsKHR(num_entries, rd_platforms, rnum_platforms);
256 }
257