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 31using namespace clover; 32 33namespace { 34 platform _clover_platform; 35} 36 37CLOVER_API cl_int 38clGetPlatformIDs(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 52platform &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 60cl_int 61clover::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 115void * 116clover::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 125namespace { 126 127cl_int 128enqueueSVMFreeARM(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 144cl_int 145enqueueSVMMapARM(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 159cl_int 160enqueueSVMMemcpyARM(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 174cl_int 175enqueueSVMMemFillARM(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 189cl_int 190enqueueSVMUnmapARM(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 200const std::unordered_map<std::string, void *> 201ext_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 222void * 223clover::GetExtensionFunctionAddress(const char *p_name) try { 224 return ext_funcs.at(p_name); 225} catch (...) { 226 return nullptr; 227} 228 229cl_int 230clover::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 235CLOVER_ICD_API cl_int 236clGetPlatformInfo(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 241CLOVER_ICD_API void * 242clGetExtensionFunctionAddress(const char *p_name) { 243 return GetExtensionFunctionAddress(p_name); 244} 245 246CLOVER_ICD_API void * 247clGetExtensionFunctionAddressForPlatform(cl_platform_id d_platform, 248 const char *p_name) { 249 return GetExtensionFunctionAddressForPlatform(d_platform, p_name); 250} 251 252CLOVER_ICD_API cl_int 253clIcdGetPlatformIDsKHR(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