summaryrefslogtreecommitdiff
path: root/src/gallium/frontends/clover/api/device.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/frontends/clover/api/device.cpp')
-rw-r--r--src/gallium/frontends/clover/api/device.cpp421
1 files changed, 421 insertions, 0 deletions
diff --git a/src/gallium/frontends/clover/api/device.cpp b/src/gallium/frontends/clover/api/device.cpp
new file mode 100644
index 00000000000..042f2eda21c
--- /dev/null
+++ b/src/gallium/frontends/clover/api/device.cpp
@@ -0,0 +1,421 @@
+//
+// Copyright 2012 Francisco Jerez
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#include "api/util.hpp"
+#include "core/platform.hpp"
+#include "core/device.hpp"
+#include "git_sha1.h"
+
+using namespace clover;
+
+CLOVER_API cl_int
+clGetDeviceIDs(cl_platform_id d_platform, cl_device_type device_type,
+ cl_uint num_entries, cl_device_id *rd_devices,
+ cl_uint *rnum_devices) try {
+ auto &platform = obj(d_platform);
+ std::vector<cl_device_id> d_devs;
+
+ if ((!num_entries && rd_devices) ||
+ (!rnum_devices && !rd_devices))
+ throw error(CL_INVALID_VALUE);
+
+ // Collect matching devices
+ for (device &dev : platform) {
+ if (((device_type & CL_DEVICE_TYPE_DEFAULT) &&
+ dev == platform.front()) ||
+ (device_type & dev.type()))
+ d_devs.push_back(desc(dev));
+ }
+
+ if (d_devs.empty())
+ throw error(CL_DEVICE_NOT_FOUND);
+
+ // ...and return the requested data.
+ if (rnum_devices)
+ *rnum_devices = d_devs.size();
+ if (rd_devices)
+ copy(range(d_devs.begin(),
+ std::min((unsigned)d_devs.size(), num_entries)),
+ rd_devices);
+
+ return CL_SUCCESS;
+
+} catch (error &e) {
+ return e.get();
+}
+
+CLOVER_API cl_int
+clCreateSubDevices(cl_device_id d_dev,
+ const cl_device_partition_property *props,
+ cl_uint num_devs, cl_device_id *rd_devs,
+ cl_uint *rnum_devs) {
+ // There are no currently supported partitioning schemes.
+ return CL_INVALID_VALUE;
+}
+
+CLOVER_API cl_int
+clRetainDevice(cl_device_id d_dev) try {
+ obj(d_dev);
+
+ // The reference count doesn't change for root devices.
+ return CL_SUCCESS;
+
+} catch (error &e) {
+ return e.get();
+}
+
+CLOVER_API cl_int
+clReleaseDevice(cl_device_id d_dev) try {
+ obj(d_dev);
+
+ // The reference count doesn't change for root devices.
+ return CL_SUCCESS;
+
+} catch (error &e) {
+ return e.get();
+}
+
+CLOVER_API cl_int
+clGetDeviceInfo(cl_device_id d_dev, cl_device_info param,
+ size_t size, void *r_buf, size_t *r_size) try {
+ property_buffer buf { r_buf, size, r_size };
+ auto &dev = obj(d_dev);
+
+ switch (param) {
+ case CL_DEVICE_TYPE:
+ buf.as_scalar<cl_device_type>() = dev.type();
+ break;
+
+ case CL_DEVICE_VENDOR_ID:
+ buf.as_scalar<cl_uint>() = dev.vendor_id();
+ break;
+
+ case CL_DEVICE_MAX_COMPUTE_UNITS:
+ buf.as_scalar<cl_uint>() = dev.max_compute_units();
+ break;
+
+ case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:
+ buf.as_scalar<cl_uint>() = dev.max_block_size().size();
+ break;
+
+ case CL_DEVICE_MAX_WORK_ITEM_SIZES:
+ buf.as_vector<size_t>() = dev.max_block_size();
+ break;
+
+ case CL_DEVICE_MAX_WORK_GROUP_SIZE:
+ buf.as_scalar<size_t>() = dev.max_threads_per_block();
+ break;
+
+ case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR:
+ buf.as_scalar<cl_uint>() = 16;
+ break;
+
+ case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT:
+ buf.as_scalar<cl_uint>() = 8;
+ break;
+
+ case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT:
+ buf.as_scalar<cl_uint>() = 4;
+ break;
+
+ case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG:
+ buf.as_scalar<cl_uint>() = 2;
+ break;
+
+ case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT:
+ buf.as_scalar<cl_uint>() = 4;
+ break;
+
+ case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE:
+ buf.as_scalar<cl_uint>() = dev.has_doubles() ? 2 : 0;
+ break;
+
+ case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF:
+ buf.as_scalar<cl_uint>() = dev.has_halves() ? 8 : 0;
+ break;
+
+ case CL_DEVICE_MAX_CLOCK_FREQUENCY:
+ buf.as_scalar<cl_uint>() = dev.max_clock_frequency();
+ break;
+
+ case CL_DEVICE_ADDRESS_BITS:
+ buf.as_scalar<cl_uint>() = dev.address_bits();
+ break;
+
+ case CL_DEVICE_MAX_READ_IMAGE_ARGS:
+ buf.as_scalar<cl_uint>() = dev.max_images_read();
+ break;
+
+ case CL_DEVICE_MAX_WRITE_IMAGE_ARGS:
+ buf.as_scalar<cl_uint>() = dev.max_images_write();
+ break;
+
+ case CL_DEVICE_MAX_MEM_ALLOC_SIZE:
+ buf.as_scalar<cl_ulong>() = dev.max_mem_alloc_size();
+ break;
+
+ case CL_DEVICE_IMAGE2D_MAX_WIDTH:
+ case CL_DEVICE_IMAGE2D_MAX_HEIGHT:
+ buf.as_scalar<size_t>() = 1 << dev.max_image_levels_2d();
+ break;
+
+ case CL_DEVICE_IMAGE3D_MAX_WIDTH:
+ case CL_DEVICE_IMAGE3D_MAX_HEIGHT:
+ case CL_DEVICE_IMAGE3D_MAX_DEPTH:
+ buf.as_scalar<size_t>() = 1 << dev.max_image_levels_3d();
+ break;
+
+ case CL_DEVICE_IMAGE_MAX_BUFFER_SIZE:
+ buf.as_scalar<size_t>() = dev.max_image_buffer_size();
+ break;
+
+ case CL_DEVICE_IMAGE_MAX_ARRAY_SIZE:
+ buf.as_scalar<size_t>() = dev.max_image_array_number();
+ break;
+
+ case CL_DEVICE_IMAGE_SUPPORT:
+ buf.as_scalar<cl_bool>() = dev.image_support();
+ break;
+
+ case CL_DEVICE_MAX_PARAMETER_SIZE:
+ buf.as_scalar<size_t>() = dev.max_mem_input();
+ break;
+
+ case CL_DEVICE_MAX_SAMPLERS:
+ buf.as_scalar<cl_uint>() = dev.max_samplers();
+ break;
+
+ case CL_DEVICE_MEM_BASE_ADDR_ALIGN:
+ buf.as_scalar<cl_uint>() = 8 *
+ std::max(dev.mem_base_addr_align(), (cl_uint) sizeof(cl_long) * 16);
+ break;
+
+ case CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE:
+ buf.as_scalar<cl_uint>() = 128;
+ break;
+
+ case CL_DEVICE_HALF_FP_CONFIG:
+ // This is the "mandated minimum half precision floating-point
+ // capability" for OpenCL 1.x.
+ buf.as_scalar<cl_device_fp_config>() =
+ CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST;
+ break;
+
+ case CL_DEVICE_SINGLE_FP_CONFIG:
+ // This is the "mandated minimum single precision floating-point
+ // capability" for OpenCL 1.1. In OpenCL 1.2, nothing is required for
+ // custom devices.
+ buf.as_scalar<cl_device_fp_config>() =
+ CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST;
+ break;
+
+ case CL_DEVICE_DOUBLE_FP_CONFIG:
+ if (dev.has_doubles())
+ // This is the "mandated minimum double precision floating-point
+ // capability"
+ buf.as_scalar<cl_device_fp_config>() =
+ CL_FP_FMA
+ | CL_FP_ROUND_TO_NEAREST
+ | CL_FP_ROUND_TO_ZERO
+ | CL_FP_ROUND_TO_INF
+ | CL_FP_INF_NAN
+ | CL_FP_DENORM;
+ else
+ buf.as_scalar<cl_device_fp_config>() = 0;
+ break;
+
+ case CL_DEVICE_GLOBAL_MEM_CACHE_TYPE:
+ buf.as_scalar<cl_device_mem_cache_type>() = CL_NONE;
+ break;
+
+ case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE:
+ buf.as_scalar<cl_uint>() = 0;
+ break;
+
+ case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE:
+ buf.as_scalar<cl_ulong>() = 0;
+ break;
+
+ case CL_DEVICE_GLOBAL_MEM_SIZE:
+ buf.as_scalar<cl_ulong>() = dev.max_mem_global();
+ break;
+
+ case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:
+ buf.as_scalar<cl_ulong>() = dev.max_const_buffer_size();
+ break;
+
+ case CL_DEVICE_MAX_CONSTANT_ARGS:
+ buf.as_scalar<cl_uint>() = dev.max_const_buffers();
+ break;
+
+ case CL_DEVICE_LOCAL_MEM_TYPE:
+ buf.as_scalar<cl_device_local_mem_type>() = CL_LOCAL;
+ break;
+
+ case CL_DEVICE_LOCAL_MEM_SIZE:
+ buf.as_scalar<cl_ulong>() = dev.max_mem_local();
+ break;
+
+ case CL_DEVICE_ERROR_CORRECTION_SUPPORT:
+ buf.as_scalar<cl_bool>() = CL_FALSE;
+ break;
+
+ case CL_DEVICE_PROFILING_TIMER_RESOLUTION:
+ buf.as_scalar<size_t>() = 0;
+ break;
+
+ case CL_DEVICE_ENDIAN_LITTLE:
+ buf.as_scalar<cl_bool>() = (dev.endianness() == PIPE_ENDIAN_LITTLE);
+ break;
+
+ case CL_DEVICE_AVAILABLE:
+ case CL_DEVICE_COMPILER_AVAILABLE:
+ case CL_DEVICE_LINKER_AVAILABLE:
+ buf.as_scalar<cl_bool>() = CL_TRUE;
+ break;
+
+ case CL_DEVICE_EXECUTION_CAPABILITIES:
+ buf.as_scalar<cl_device_exec_capabilities>() = CL_EXEC_KERNEL;
+ break;
+
+ case CL_DEVICE_QUEUE_PROPERTIES:
+ buf.as_scalar<cl_command_queue_properties>() = CL_QUEUE_PROFILING_ENABLE;
+ break;
+
+ case CL_DEVICE_BUILT_IN_KERNELS:
+ buf.as_string() = "";
+ break;
+
+ case CL_DEVICE_NAME:
+ buf.as_string() = dev.device_name();
+ break;
+
+ case CL_DEVICE_VENDOR:
+ buf.as_string() = dev.vendor_name();
+ break;
+
+ case CL_DRIVER_VERSION:
+ buf.as_string() = PACKAGE_VERSION;
+ break;
+
+ case CL_DEVICE_PROFILE:
+ buf.as_string() = "FULL_PROFILE";
+ break;
+
+ case CL_DEVICE_VERSION:
+ buf.as_string() = "OpenCL " + dev.device_version() + " Mesa " PACKAGE_VERSION MESA_GIT_SHA1;
+ break;
+
+ case CL_DEVICE_EXTENSIONS:
+ buf.as_string() = dev.supported_extensions();
+ break;
+
+ case CL_DEVICE_PLATFORM:
+ buf.as_scalar<cl_platform_id>() = desc(dev.platform);
+ break;
+
+ case CL_DEVICE_HOST_UNIFIED_MEMORY:
+ buf.as_scalar<cl_bool>() = dev.has_unified_memory();
+ break;
+
+ case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR:
+ buf.as_scalar<cl_uint>() = 16;
+ break;
+
+ case CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT:
+ buf.as_scalar<cl_uint>() = 8;
+ break;
+
+ case CL_DEVICE_NATIVE_VECTOR_WIDTH_INT:
+ buf.as_scalar<cl_uint>() = 4;
+ break;
+
+ case CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG:
+ buf.as_scalar<cl_uint>() = 2;
+ break;
+
+ case CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT:
+ buf.as_scalar<cl_uint>() = 4;
+ break;
+
+ case CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE:
+ buf.as_scalar<cl_uint>() = dev.has_doubles() ? 2 : 0;
+ break;
+
+ case CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF:
+ buf.as_scalar<cl_uint>() = dev.has_halves() ? 8 : 0;
+ break;
+
+ case CL_DEVICE_OPENCL_C_VERSION:
+ buf.as_string() = "OpenCL C " + dev.device_clc_version() + " ";
+ break;
+
+ case CL_DEVICE_PRINTF_BUFFER_SIZE:
+ // Per the spec, the minimum value for the FULL profile is 1 MB.
+ // However, clover is not ready yet to support it
+ buf.as_scalar<size_t>() = 0 /* 1024 */;
+ break;
+
+ case CL_DEVICE_PREFERRED_INTEROP_USER_SYNC:
+ buf.as_scalar<cl_bool>() = CL_TRUE;
+ break;
+
+ case CL_DEVICE_PARENT_DEVICE:
+ buf.as_scalar<cl_device_id>() = NULL;
+ break;
+
+ case CL_DEVICE_PARTITION_MAX_SUB_DEVICES:
+ buf.as_scalar<cl_uint>() = 0;
+ break;
+
+ case CL_DEVICE_PARTITION_PROPERTIES:
+ buf.as_vector<cl_device_partition_property>() =
+ desc(property_list<cl_device_partition_property>());
+ break;
+
+ case CL_DEVICE_PARTITION_AFFINITY_DOMAIN:
+ buf.as_scalar<cl_device_affinity_domain>() = 0;
+ break;
+
+ case CL_DEVICE_PARTITION_TYPE:
+ buf.as_vector<cl_device_partition_property>() =
+ desc(property_list<cl_device_partition_property>());
+ break;
+
+ case CL_DEVICE_REFERENCE_COUNT:
+ buf.as_scalar<cl_uint>() = 1;
+ break;
+
+ case CL_DEVICE_SVM_CAPABILITIES:
+ case CL_DEVICE_SVM_CAPABILITIES_ARM:
+ buf.as_scalar<cl_device_svm_capabilities>() = dev.svm_support();
+ break;
+
+ default:
+ throw error(CL_INVALID_VALUE);
+ }
+
+ return CL_SUCCESS;
+
+} catch (error &e) {
+ return e.get();
+}