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