// // 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 "core/device.hpp" #include "pipe/p_screen.h" #include "pipe/p_state.h" using namespace clover; namespace { template std::vector get_compute_param(pipe_screen *pipe, pipe_compute_cap cap) { int sz = pipe->get_compute_param(pipe, cap, NULL); std::vector v(sz / sizeof(T)); pipe->get_compute_param(pipe, cap, &v.front()); return v; } } _cl_device_id::_cl_device_id(clover::platform &platform, pipe_loader_device *ldev) : platform(platform), ldev(ldev) { pipe = pipe_loader_create_screen(ldev, PIPE_SEARCH_DIR); if (!pipe || !pipe->get_param(pipe, PIPE_CAP_COMPUTE)) throw error(CL_INVALID_DEVICE); } _cl_device_id::_cl_device_id(_cl_device_id &&dev) : platform(dev.platform), pipe(dev.pipe), ldev(dev.ldev) { dev.pipe = NULL; dev.ldev = NULL; } _cl_device_id::~_cl_device_id() { if (pipe) pipe->destroy(pipe); if (ldev) pipe_loader_release(&ldev, 1); } _cl_device_id & _cl_device_id::operator=(_cl_device_id dev) { assert(&platform == &dev.platform); std::swap(pipe, dev.pipe); std::swap(ldev, dev.ldev); return *this; } cl_device_type _cl_device_id::type() const { switch (ldev->type) { case PIPE_LOADER_DEVICE_SOFTWARE: return CL_DEVICE_TYPE_CPU; case PIPE_LOADER_DEVICE_PCI: return CL_DEVICE_TYPE_GPU; default: assert(0); return 0; } } cl_uint _cl_device_id::vendor_id() const { switch (ldev->type) { case PIPE_LOADER_DEVICE_SOFTWARE: return 0; case PIPE_LOADER_DEVICE_PCI: return ldev->u.pci.vendor_id; default: assert(0); return 0; } } size_t _cl_device_id::max_images_read() const { return PIPE_MAX_SHADER_RESOURCES; } size_t _cl_device_id::max_images_write() const { return PIPE_MAX_SHADER_RESOURCES; } cl_uint _cl_device_id::max_image_levels_2d() const { return pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_2D_LEVELS); } cl_uint _cl_device_id::max_image_levels_3d() const { return pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_3D_LEVELS); } cl_uint _cl_device_id::max_samplers() const { return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE, PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS); } cl_ulong _cl_device_id::max_mem_global() const { return get_compute_param(pipe, PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE)[0]; } cl_ulong _cl_device_id::max_mem_local() const { return get_compute_param(pipe, PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE)[0]; } cl_ulong _cl_device_id::max_mem_input() const { return get_compute_param(pipe, PIPE_COMPUTE_CAP_MAX_INPUT_SIZE)[0]; } cl_ulong _cl_device_id::max_const_buffer_size() const { return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE, PIPE_SHADER_CAP_MAX_CONSTS) * 16; } cl_uint _cl_device_id::max_const_buffers() const { return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE, PIPE_SHADER_CAP_MAX_CONST_BUFFERS); } size_t _cl_device_id::max_threads_per_block() const { return get_compute_param( pipe, PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK)[0]; } cl_ulong _cl_device_id::max_mem_alloc_size() const { return get_compute_param(pipe, PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE)[0]; } std::vector _cl_device_id::max_block_size() const { auto v = get_compute_param(pipe, PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE); return { v.begin(), v.end() }; } std::string _cl_device_id::device_name() const { return pipe->get_name(pipe); } std::string _cl_device_id::vendor_name() const { return pipe->get_vendor(pipe); } enum pipe_shader_ir _cl_device_id::ir_format() const { return (enum pipe_shader_ir) pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE, PIPE_SHADER_CAP_PREFERRED_IR); } std::string _cl_device_id::ir_target() const { std::vector target = get_compute_param(pipe, PIPE_COMPUTE_CAP_IR_TARGET); return { target.data() }; } enum pipe_endian _cl_device_id::endianness() const { return (enum pipe_endian)pipe->get_param(pipe, PIPE_CAP_ENDIANNESS); }