bc93f91d0ec85e3f95b78ae342c375407515dd77
[mesa.git] / src / gallium / state_trackers / clover / api / device.cpp
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 "api/util.hpp"
24 #include "core/platform.hpp"
25 #include "core/device.hpp"
26
27 using namespace clover;
28
29 CLOVER_API cl_int
30 clGetDeviceIDs(cl_platform_id d_platform, cl_device_type device_type,
31 cl_uint num_entries, cl_device_id *rd_devices,
32 cl_uint *rnum_devices) try {
33 auto &platform = obj(d_platform);
34 std::vector<cl_device_id> d_devs;
35
36 if ((!num_entries && rd_devices) ||
37 (!rnum_devices && !rd_devices))
38 throw error(CL_INVALID_VALUE);
39
40 // Collect matching devices
41 for (device &dev : platform) {
42 if (((device_type & CL_DEVICE_TYPE_DEFAULT) &&
43 dev == platform.front()) ||
44 (device_type & dev.type()))
45 d_devs.push_back(desc(dev));
46 }
47
48 if (d_devs.empty())
49 throw error(CL_DEVICE_NOT_FOUND);
50
51 // ...and return the requested data.
52 if (rnum_devices)
53 *rnum_devices = d_devs.size();
54 if (rd_devices)
55 copy(range(d_devs.begin(),
56 std::min((unsigned)d_devs.size(), num_entries)),
57 rd_devices);
58
59 return CL_SUCCESS;
60
61 } catch (error &e) {
62 return e.get();
63 }
64
65 CLOVER_API cl_int
66 clCreateSubDevices(cl_device_id d_dev,
67 const cl_device_partition_property *props,
68 cl_uint num_devs, cl_device_id *rd_devs,
69 cl_uint *rnum_devs) {
70 // There are no currently supported partitioning schemes.
71 return CL_INVALID_VALUE;
72 }
73
74 CLOVER_API cl_int
75 clRetainDevice(cl_device_id d_dev) try {
76 obj(d_dev);
77
78 // The reference count doesn't change for root devices.
79 return CL_SUCCESS;
80
81 } catch (error &e) {
82 return e.get();
83 }
84
85 CLOVER_API cl_int
86 clReleaseDevice(cl_device_id d_dev) try {
87 obj(d_dev);
88
89 // The reference count doesn't change for root devices.
90 return CL_SUCCESS;
91
92 } catch (error &e) {
93 return e.get();
94 }
95
96 CLOVER_API cl_int
97 clGetDeviceInfo(cl_device_id d_dev, cl_device_info param,
98 size_t size, void *r_buf, size_t *r_size) try {
99 property_buffer buf { r_buf, size, r_size };
100 auto &dev = obj(d_dev);
101
102 switch (param) {
103 case CL_DEVICE_TYPE:
104 buf.as_scalar<cl_device_type>() = dev.type();
105 break;
106
107 case CL_DEVICE_VENDOR_ID:
108 buf.as_scalar<cl_uint>() = dev.vendor_id();
109 break;
110
111 case CL_DEVICE_MAX_COMPUTE_UNITS:
112 buf.as_scalar<cl_uint>() = dev.max_compute_units();
113 break;
114
115 case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:
116 buf.as_scalar<cl_uint>() = dev.max_block_size().size();
117 break;
118
119 case CL_DEVICE_MAX_WORK_ITEM_SIZES:
120 buf.as_vector<size_t>() = dev.max_block_size();
121 break;
122
123 case CL_DEVICE_MAX_WORK_GROUP_SIZE:
124 buf.as_scalar<size_t>() = dev.max_threads_per_block();
125 break;
126
127 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR:
128 buf.as_scalar<cl_uint>() = 16;
129 break;
130
131 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT:
132 buf.as_scalar<cl_uint>() = 8;
133 break;
134
135 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT:
136 buf.as_scalar<cl_uint>() = 4;
137 break;
138
139 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG:
140 buf.as_scalar<cl_uint>() = 2;
141 break;
142
143 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT:
144 buf.as_scalar<cl_uint>() = 4;
145 break;
146
147 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE:
148 buf.as_scalar<cl_uint>() = dev.has_doubles() ? 2 : 0;
149 break;
150
151 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF:
152 buf.as_scalar<cl_uint>() = 0;
153 break;
154
155 case CL_DEVICE_MAX_CLOCK_FREQUENCY:
156 buf.as_scalar<cl_uint>() = dev.max_clock_frequency();
157 break;
158
159 case CL_DEVICE_ADDRESS_BITS:
160 buf.as_scalar<cl_uint>() = 32;
161 break;
162
163 case CL_DEVICE_MAX_READ_IMAGE_ARGS:
164 buf.as_scalar<cl_uint>() = dev.max_images_read();
165 break;
166
167 case CL_DEVICE_MAX_WRITE_IMAGE_ARGS:
168 buf.as_scalar<cl_uint>() = dev.max_images_write();
169 break;
170
171 case CL_DEVICE_MAX_MEM_ALLOC_SIZE:
172 buf.as_scalar<cl_ulong>() = dev.max_mem_alloc_size();
173 break;
174
175 case CL_DEVICE_IMAGE2D_MAX_WIDTH:
176 case CL_DEVICE_IMAGE2D_MAX_HEIGHT:
177 buf.as_scalar<size_t>() = 1 << dev.max_image_levels_2d();
178 break;
179
180 case CL_DEVICE_IMAGE3D_MAX_WIDTH:
181 case CL_DEVICE_IMAGE3D_MAX_HEIGHT:
182 case CL_DEVICE_IMAGE3D_MAX_DEPTH:
183 buf.as_scalar<size_t>() = 1 << dev.max_image_levels_3d();
184 break;
185
186 case CL_DEVICE_IMAGE_SUPPORT:
187 buf.as_scalar<cl_bool>() = dev.image_support();
188 break;
189
190 case CL_DEVICE_MAX_PARAMETER_SIZE:
191 buf.as_scalar<size_t>() = dev.max_mem_input();
192 break;
193
194 case CL_DEVICE_MAX_SAMPLERS:
195 buf.as_scalar<cl_uint>() = dev.max_samplers();
196 break;
197
198 case CL_DEVICE_MEM_BASE_ADDR_ALIGN:
199 buf.as_scalar<cl_uint>() = 128 * 8;
200 break;
201
202 case CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE:
203 buf.as_scalar<cl_uint>() = 128;
204 break;
205
206 case CL_DEVICE_SINGLE_FP_CONFIG:
207 // This is the "mandated minimum single precision floating-point
208 // capability" for OpenCL 1.1. In OpenCL 1.2, nothing is required for
209 // custom devices.
210 buf.as_scalar<cl_device_fp_config>() =
211 CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST;
212 break;
213
214 case CL_DEVICE_DOUBLE_FP_CONFIG:
215 if (dev.has_doubles())
216 // This is the "mandated minimum double precision floating-point
217 // capability"
218 buf.as_scalar<cl_device_fp_config>() =
219 CL_FP_FMA
220 | CL_FP_ROUND_TO_NEAREST
221 | CL_FP_ROUND_TO_ZERO
222 | CL_FP_ROUND_TO_INF
223 | CL_FP_INF_NAN
224 | CL_FP_DENORM;
225 else
226 buf.as_scalar<cl_device_fp_config>() = 0;
227 break;
228
229 case CL_DEVICE_GLOBAL_MEM_CACHE_TYPE:
230 buf.as_scalar<cl_device_mem_cache_type>() = CL_NONE;
231 break;
232
233 case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE:
234 buf.as_scalar<cl_uint>() = 0;
235 break;
236
237 case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE:
238 buf.as_scalar<cl_ulong>() = 0;
239 break;
240
241 case CL_DEVICE_GLOBAL_MEM_SIZE:
242 buf.as_scalar<cl_ulong>() = dev.max_mem_global();
243 break;
244
245 case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:
246 buf.as_scalar<cl_ulong>() = dev.max_const_buffer_size();
247 break;
248
249 case CL_DEVICE_MAX_CONSTANT_ARGS:
250 buf.as_scalar<cl_uint>() = dev.max_const_buffers();
251 break;
252
253 case CL_DEVICE_LOCAL_MEM_TYPE:
254 buf.as_scalar<cl_device_local_mem_type>() = CL_LOCAL;
255 break;
256
257 case CL_DEVICE_LOCAL_MEM_SIZE:
258 buf.as_scalar<cl_ulong>() = dev.max_mem_local();
259 break;
260
261 case CL_DEVICE_ERROR_CORRECTION_SUPPORT:
262 buf.as_scalar<cl_bool>() = CL_FALSE;
263 break;
264
265 case CL_DEVICE_PROFILING_TIMER_RESOLUTION:
266 buf.as_scalar<size_t>() = 0;
267 break;
268
269 case CL_DEVICE_ENDIAN_LITTLE:
270 buf.as_scalar<cl_bool>() = (dev.endianness() == PIPE_ENDIAN_LITTLE);
271 break;
272
273 case CL_DEVICE_AVAILABLE:
274 case CL_DEVICE_COMPILER_AVAILABLE:
275 buf.as_scalar<cl_bool>() = CL_TRUE;
276 break;
277
278 case CL_DEVICE_EXECUTION_CAPABILITIES:
279 buf.as_scalar<cl_device_exec_capabilities>() = CL_EXEC_KERNEL;
280 break;
281
282 case CL_DEVICE_QUEUE_PROPERTIES:
283 buf.as_scalar<cl_command_queue_properties>() = CL_QUEUE_PROFILING_ENABLE;
284 break;
285
286 case CL_DEVICE_NAME:
287 buf.as_string() = dev.device_name();
288 break;
289
290 case CL_DEVICE_VENDOR:
291 buf.as_string() = dev.vendor_name();
292 break;
293
294 case CL_DRIVER_VERSION:
295 buf.as_string() = PACKAGE_VERSION;
296 break;
297
298 case CL_DEVICE_PROFILE:
299 buf.as_string() = "FULL_PROFILE";
300 break;
301
302 case CL_DEVICE_VERSION:
303 buf.as_string() = "OpenCL 1.1 MESA " PACKAGE_VERSION;
304 break;
305
306 case CL_DEVICE_EXTENSIONS:
307 buf.as_string() =
308 "cl_khr_global_int32_base_atomics"
309 " cl_khr_global_int32_extended_atomics"
310 " cl_khr_local_int32_base_atomics"
311 " cl_khr_local_int32_extended_atomics"
312 " cl_khr_byte_addressable_store"
313 + std::string(dev.has_doubles() ? " cl_khr_fp64" : "");
314 break;
315
316 case CL_DEVICE_PLATFORM:
317 buf.as_scalar<cl_platform_id>() = desc(dev.platform);
318 break;
319
320 case CL_DEVICE_HOST_UNIFIED_MEMORY:
321 buf.as_scalar<cl_bool>() = CL_TRUE;
322 break;
323
324 case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR:
325 buf.as_scalar<cl_uint>() = 16;
326 break;
327
328 case CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT:
329 buf.as_scalar<cl_uint>() = 8;
330 break;
331
332 case CL_DEVICE_NATIVE_VECTOR_WIDTH_INT:
333 buf.as_scalar<cl_uint>() = 4;
334 break;
335
336 case CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG:
337 buf.as_scalar<cl_uint>() = 2;
338 break;
339
340 case CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT:
341 buf.as_scalar<cl_uint>() = 4;
342 break;
343
344 case CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE:
345 buf.as_scalar<cl_uint>() = dev.has_doubles() ? 2 : 0;
346 break;
347
348 case CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF:
349 buf.as_scalar<cl_uint>() = 0;
350 break;
351
352 case CL_DEVICE_OPENCL_C_VERSION:
353 buf.as_string() = "OpenCL C 1.1 ";
354 break;
355
356 case CL_DEVICE_PARENT_DEVICE:
357 buf.as_scalar<cl_device_id>() = NULL;
358 break;
359
360 case CL_DEVICE_PARTITION_MAX_SUB_DEVICES:
361 buf.as_scalar<cl_uint>() = 0;
362 break;
363
364 case CL_DEVICE_PARTITION_PROPERTIES:
365 buf.as_vector<cl_device_partition_property>() =
366 desc(property_list<cl_device_partition_property>());
367 break;
368
369 case CL_DEVICE_PARTITION_AFFINITY_DOMAIN:
370 buf.as_scalar<cl_device_affinity_domain>() = 0;
371 break;
372
373 case CL_DEVICE_PARTITION_TYPE:
374 buf.as_vector<cl_device_partition_property>() =
375 desc(property_list<cl_device_partition_property>());
376 break;
377
378 case CL_DEVICE_REFERENCE_COUNT:
379 buf.as_scalar<cl_uint>() = 1;
380 break;
381
382 default:
383 throw error(CL_INVALID_VALUE);
384 }
385
386 return CL_SUCCESS;
387
388 } catch (error &e) {
389 return e.get();
390 }