blob: 9a81ac61fae3a8609f1addde277dfc4f42beafc0 [file] [log] [blame]
Francisco Jerezc6db1b32012-04-20 16:56:19 +02001//
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
Kenneth Graunkef0cb66b2013-04-21 13:52:08 -070017// 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.
Francisco Jerezc6db1b32012-04-20 16:56:19 +020021//
22
Aaron Watry5e253fe2017-08-16 20:44:41 -050023#include <unistd.h>
Francisco Jerezc6db1b32012-04-20 16:56:19 +020024#include "core/device.hpp"
Francisco Jerezc4578d22014-02-18 15:07:11 +010025#include "core/platform.hpp"
Francisco Jerezc6db1b32012-04-20 16:56:19 +020026#include "pipe/p_screen.h"
27#include "pipe/p_state.h"
Eric Anholt0c31fe92019-04-29 15:38:24 -070028#include "util/bitscan.h"
Aaron Watry95ae6c02017-08-09 22:02:30 -050029#include "util/u_debug.h"
Francisco Jerezc6db1b32012-04-20 16:56:19 +020030
31using namespace clover;
32
33namespace {
34 template<typename T>
35 std::vector<T>
Bas Nieuwenhuizen1a5c8c22016-03-25 02:06:50 +010036 get_compute_param(pipe_screen *pipe, pipe_shader_ir ir_format,
37 pipe_compute_cap cap) {
38 int sz = pipe->get_compute_param(pipe, ir_format, cap, NULL);
Francisco Jerezc6db1b32012-04-20 16:56:19 +020039 std::vector<T> v(sz / sizeof(T));
40
Bas Nieuwenhuizen1a5c8c22016-03-25 02:06:50 +010041 pipe->get_compute_param(pipe, ir_format, cap, &v.front());
Francisco Jerezc6db1b32012-04-20 16:56:19 +020042 return v;
43 }
44}
45
Francisco Jerezc9e009b2013-09-15 20:06:57 -070046device::device(clover::platform &platform, pipe_loader_device *ldev) :
Francisco Jerez1a8ad6c2013-04-06 14:35:00 +020047 platform(platform), ldev(ldev) {
Nicolai Hähnleae7283d2017-08-03 15:02:09 +020048 pipe = pipe_loader_create_screen(ldev);
Karol Herbstdeb04ad2019-08-06 20:35:48 +020049 if (pipe && pipe->get_param(pipe, PIPE_CAP_COMPUTE)) {
50 if (supports_ir(PIPE_SHADER_IR_NATIVE))
51 return;
52#ifdef HAVE_CLOVER_SPIRV
53 if (supports_ir(PIPE_SHADER_IR_NIR_SERIALIZED))
54 return;
55#endif
Tom Stellardc5f0c982014-05-08 21:08:32 -040056 }
Karol Herbstdeb04ad2019-08-06 20:35:48 +020057 if (pipe)
58 pipe->destroy(pipe);
59 throw error(CL_INVALID_DEVICE);
Francisco Jerezc6db1b32012-04-20 16:56:19 +020060}
61
Francisco Jerezc9e009b2013-09-15 20:06:57 -070062device::~device() {
Francisco Jerezc6db1b32012-04-20 16:56:19 +020063 if (pipe)
64 pipe->destroy(pipe);
65 if (ldev)
66 pipe_loader_release(&ldev, 1);
67}
68
Francisco Jerez369419f2013-09-16 21:11:16 -070069bool
70device::operator==(const device &dev) const {
71 return this == &dev;
72}
73
Francisco Jerezc6db1b32012-04-20 16:56:19 +020074cl_device_type
Francisco Jerezc9e009b2013-09-15 20:06:57 -070075device::type() const {
Francisco Jerezc6db1b32012-04-20 16:56:19 +020076 switch (ldev->type) {
77 case PIPE_LOADER_DEVICE_SOFTWARE:
78 return CL_DEVICE_TYPE_CPU;
79 case PIPE_LOADER_DEVICE_PCI:
Emil Velikov26458422014-01-11 05:19:36 +000080 case PIPE_LOADER_DEVICE_PLATFORM:
Francisco Jerezc6db1b32012-04-20 16:56:19 +020081 return CL_DEVICE_TYPE_GPU;
82 default:
Francisco Jerez27c51b52014-10-08 17:29:14 +030083 unreachable("Unknown device type.");
Francisco Jerezc6db1b32012-04-20 16:56:19 +020084 }
85}
86
87cl_uint
Francisco Jerezc9e009b2013-09-15 20:06:57 -070088device::vendor_id() const {
Francisco Jerezc6db1b32012-04-20 16:56:19 +020089 switch (ldev->type) {
90 case PIPE_LOADER_DEVICE_SOFTWARE:
Emil Velikov26458422014-01-11 05:19:36 +000091 case PIPE_LOADER_DEVICE_PLATFORM:
Francisco Jerezc6db1b32012-04-20 16:56:19 +020092 return 0;
93 case PIPE_LOADER_DEVICE_PCI:
Francisco Jerez03e3bc42012-05-16 15:43:29 +020094 return ldev->u.pci.vendor_id;
Francisco Jerezc6db1b32012-04-20 16:56:19 +020095 default:
Francisco Jerez27c51b52014-10-08 17:29:14 +030096 unreachable("Unknown device type.");
Francisco Jerezc6db1b32012-04-20 16:56:19 +020097 }
98}
99
100size_t
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700101device::max_images_read() const {
Marek Olšákb73bec02015-07-05 14:34:13 +0200102 return PIPE_MAX_SHADER_IMAGES;
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200103}
104
105size_t
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700106device::max_images_write() const {
Marek Olšákb73bec02015-07-05 14:34:13 +0200107 return PIPE_MAX_SHADER_IMAGES;
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200108}
109
Serge Martin05fcc732016-10-01 18:51:11 +0200110size_t
111device::max_image_buffer_size() const {
112 return pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE);
113}
114
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200115cl_uint
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700116device::max_image_levels_2d() const {
Eric Anholt0c31fe92019-04-29 15:38:24 -0700117 return util_last_bit(pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_2D_SIZE));
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200118}
119
120cl_uint
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700121device::max_image_levels_3d() const {
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200122 return pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_3D_LEVELS);
123}
124
Serge Martin05fcc732016-10-01 18:51:11 +0200125size_t
126device::max_image_array_number() const {
127 return pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS);
128}
129
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200130cl_uint
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700131device::max_samplers() const {
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200132 return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
133 PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS);
134}
135
136cl_ulong
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700137device::max_mem_global() const {
Bas Nieuwenhuizen1a5c8c22016-03-25 02:06:50 +0100138 return get_compute_param<uint64_t>(pipe, ir_format(),
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200139 PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE)[0];
140}
141
142cl_ulong
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700143device::max_mem_local() const {
Bas Nieuwenhuizen1a5c8c22016-03-25 02:06:50 +0100144 return get_compute_param<uint64_t>(pipe, ir_format(),
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200145 PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE)[0];
146}
147
148cl_ulong
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700149device::max_mem_input() const {
Bas Nieuwenhuizen1a5c8c22016-03-25 02:06:50 +0100150 return get_compute_param<uint64_t>(pipe, ir_format(),
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200151 PIPE_COMPUTE_CAP_MAX_INPUT_SIZE)[0];
152}
153
154cl_ulong
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700155device::max_const_buffer_size() const {
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200156 return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
Marek Olšák04f2c882014-07-24 20:32:08 +0200157 PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE);
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200158}
159
160cl_uint
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700161device::max_const_buffers() const {
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200162 return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
163 PIPE_SHADER_CAP_MAX_CONST_BUFFERS);
164}
165
Christoph Bumiller5c9bccc2012-05-12 19:32:46 +0200166size_t
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700167device::max_threads_per_block() const {
Christoph Bumiller5c9bccc2012-05-12 19:32:46 +0200168 return get_compute_param<uint64_t>(
Bas Nieuwenhuizen1a5c8c22016-03-25 02:06:50 +0100169 pipe, ir_format(), PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK)[0];
Christoph Bumiller5c9bccc2012-05-12 19:32:46 +0200170}
171
Tom Stellard71682cf2012-09-17 14:29:49 +0000172cl_ulong
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700173device::max_mem_alloc_size() const {
Bas Nieuwenhuizen1a5c8c22016-03-25 02:06:50 +0100174 return get_compute_param<uint64_t>(pipe, ir_format(),
Tom Stellard71682cf2012-09-17 14:29:49 +0000175 PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE)[0];
176}
177
Tom Stellardca848e82014-04-18 16:28:41 +0200178cl_uint
179device::max_clock_frequency() const {
Bas Nieuwenhuizen1a5c8c22016-03-25 02:06:50 +0100180 return get_compute_param<uint32_t>(pipe, ir_format(),
Tom Stellardca848e82014-04-18 16:28:41 +0200181 PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY)[0];
182}
183
Bruno Jiménez2a0dffa2014-05-30 17:31:12 +0200184cl_uint
185device::max_compute_units() const {
Bas Nieuwenhuizen1a5c8c22016-03-25 02:06:50 +0100186 return get_compute_param<uint32_t>(pipe, ir_format(),
Bruno Jiménez2a0dffa2014-05-30 17:31:12 +0200187 PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS)[0];
188}
189
Tom Stellard0ec85872014-07-23 20:37:08 -0400190bool
191device::image_support() const {
Bas Nieuwenhuizen1a5c8c22016-03-25 02:06:50 +0100192 return get_compute_param<uint32_t>(pipe, ir_format(),
Tom Stellard0ec85872014-07-23 20:37:08 -0400193 PIPE_COMPUTE_CAP_IMAGES_SUPPORTED)[0];
194}
195
Tom Stellardc97e9022014-07-02 15:42:43 -0400196bool
197device::has_doubles() const {
Nicolai Hähnlea020cb32017-01-27 10:35:13 +0100198 return pipe->get_param(pipe, PIPE_CAP_DOUBLES);
Tom Stellardc97e9022014-07-02 15:42:43 -0400199}
200
Aaron Watryd364ab42017-06-02 21:51:43 -0500201bool
Jan Veselyfdf0f1d2017-09-01 17:48:39 -0400202device::has_halves() const {
203 return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
204 PIPE_SHADER_CAP_FP16);
205}
206
207bool
Jan Veselyf67ceef2017-09-20 16:06:10 -0400208device::has_int64_atomics() const {
209 return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
210 PIPE_SHADER_CAP_INT64_ATOMICS);
211}
212
213bool
Aaron Watryd364ab42017-06-02 21:51:43 -0500214device::has_unified_memory() const {
215 return pipe->get_param(pipe, PIPE_CAP_UMA);
216}
217
Aaron Watry5e253fe2017-08-16 20:44:41 -0500218cl_uint
219device::mem_base_addr_align() const {
220 return sysconf(_SC_PAGESIZE);
221}
222
Karol Herbst035e8822018-05-21 12:19:42 +0200223cl_device_svm_capabilities
224device::svm_support() const {
225 // Without CAP_RESOURCE_FROM_USER_MEMORY SVM and CL_MEM_USE_HOST_PTR
226 // interactions won't work according to spec as clover manages a GPU side
227 // copy of the host data.
228 //
229 // The biggest problem are memory buffers created with CL_MEM_USE_HOST_PTR,
230 // but the application and/or the kernel updates the memory via SVM and not
231 // the cl_mem buffer.
232 // We can't even do proper tracking on what memory might have been accessed
233 // as the host ptr to the buffer could be within a SVM region, where through
234 // the CL API there is no reliable way of knowing if a certain cl_mem buffer
235 // was accessed by a kernel or not and the runtime can't reliably know from
236 // which side the GPU buffer content needs to be updated.
237 //
238 // Another unsolvable scenario is a cl_mem object passed by cl_mem reference
239 // and SVM pointer into the same kernel at the same time.
240 if (pipe->get_param(pipe, PIPE_CAP_RESOURCE_FROM_USER_MEMORY) &&
241 pipe->get_param(pipe, PIPE_CAP_SYSTEM_SVM))
Karol Herbsta2186582019-05-22 22:34:09 +0200242 // we can emulate all lower levels if we support fine grain system
243 return CL_DEVICE_SVM_FINE_GRAIN_SYSTEM |
244 CL_DEVICE_SVM_COARSE_GRAIN_BUFFER |
245 CL_DEVICE_SVM_FINE_GRAIN_BUFFER;
Karol Herbst035e8822018-05-21 12:19:42 +0200246 return 0;
247}
248
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200249std::vector<size_t>
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700250device::max_block_size() const {
Bas Nieuwenhuizen1a5c8c22016-03-25 02:06:50 +0100251 auto v = get_compute_param<uint64_t>(pipe, ir_format(),
252 PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE);
Francisco Jerezb70736f2012-05-12 19:33:33 +0200253 return { v.begin(), v.end() };
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200254}
255
Grigori Goronzyd15b32e2015-05-28 13:01:51 +0200256cl_uint
257device::subgroup_size() const {
Bas Nieuwenhuizen1a5c8c22016-03-25 02:06:50 +0100258 return get_compute_param<uint32_t>(pipe, ir_format(),
259 PIPE_COMPUTE_CAP_SUBGROUP_SIZE)[0];
Grigori Goronzyd15b32e2015-05-28 13:01:51 +0200260}
261
Jan Vesely083746b2016-08-28 04:08:15 -0400262cl_uint
263device::address_bits() const {
264 return get_compute_param<uint32_t>(pipe, ir_format(),
265 PIPE_COMPUTE_CAP_ADDRESS_BITS)[0];
266}
267
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200268std::string
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700269device::device_name() const {
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200270 return pipe->get_name(pipe);
271}
272
273std::string
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700274device::vendor_name() const {
Giuseppe Bilotta7932b302015-03-22 07:21:02 +0100275 return pipe->get_device_vendor(pipe);
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200276}
277
Tom Stellard613323b2012-04-23 12:09:08 -0400278enum pipe_shader_ir
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700279device::ir_format() const {
Karol Herbstdeb04ad2019-08-06 20:35:48 +0200280 if (supports_ir(PIPE_SHADER_IR_NATIVE))
281 return PIPE_SHADER_IR_NATIVE;
282
283 assert(supports_ir(PIPE_SHADER_IR_NIR_SERIALIZED));
284 return PIPE_SHADER_IR_NIR_SERIALIZED;
Tom Stellard613323b2012-04-23 12:09:08 -0400285}
286
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200287std::string
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700288device::ir_target() const {
289 std::vector<char> target = get_compute_param<char>(
Bas Nieuwenhuizen1a5c8c22016-03-25 02:06:50 +0100290 pipe, ir_format(), PIPE_COMPUTE_CAP_IR_TARGET);
Tom Stellard613323b2012-04-23 12:09:08 -0400291 return { target.data() };
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200292}
Tom Stellard8c9d3c62013-07-09 21:21:40 -0700293
294enum pipe_endian
Francisco Jerezc9e009b2013-09-15 20:06:57 -0700295device::endianness() const {
Tom Stellard8c9d3c62013-07-09 21:21:40 -0700296 return (enum pipe_endian)pipe->get_param(pipe, PIPE_CAP_ENDIANNESS);
297}
Aaron Watry293b3e02017-07-21 21:17:50 -0500298
299std::string
300device::device_version() const {
Aaron Watry95ae6c02017-08-09 22:02:30 -0500301 static const std::string device_version =
302 debug_get_option("CLOVER_DEVICE_VERSION_OVERRIDE", "1.1");
303 return device_version;
Aaron Watry293b3e02017-07-21 21:17:50 -0500304}
305
306std::string
307device::device_clc_version() const {
Aaron Watry95ae6c02017-08-09 22:02:30 -0500308 static const std::string device_clc_version =
309 debug_get_option("CLOVER_DEVICE_CLC_VERSION_OVERRIDE", "1.1");
310 return device_clc_version;
Aaron Watry293b3e02017-07-21 21:17:50 -0500311}
Pierre Moreau505ec3a2017-10-03 21:07:45 +0200312
313bool
314device::supports_ir(enum pipe_shader_ir ir) const {
315 return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
316 PIPE_SHADER_CAP_SUPPORTED_IRS) & (1 << ir);
317}
Pierre Moreaub0336202018-01-21 18:49:00 +0100318
319std::string
320device::supported_extensions() const {
321 return
322 "cl_khr_byte_addressable_store"
323 " cl_khr_global_int32_base_atomics"
324 " cl_khr_global_int32_extended_atomics"
325 " cl_khr_local_int32_base_atomics"
326 " cl_khr_local_int32_extended_atomics"
327 + std::string(has_int64_atomics() ? " cl_khr_int64_base_atomics" : "")
328 + std::string(has_int64_atomics() ? " cl_khr_int64_extended_atomics" : "")
329 + std::string(has_doubles() ? " cl_khr_fp64" : "")
330 + std::string(has_halves() ? " cl_khr_fp16" : "");
331}
Karol Herbstdeb04ad2019-08-06 20:35:48 +0200332
333const void *
334device::get_compiler_options(enum pipe_shader_ir ir) const {
335 return pipe->get_compiler_options(pipe, ir, PIPE_SHADER_COMPUTE);
336}