Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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 "core/device.hpp"
  24. #include "core/platform.hpp"
  25. #include "pipe/p_screen.h"
  26. #include "pipe/p_state.h"
  27.  
  28. using namespace clover;
  29.  
  30. namespace {
  31.    template<typename T>
  32.    std::vector<T>
  33.    get_compute_param(pipe_screen *pipe, pipe_compute_cap cap) {
  34.       int sz = pipe->get_compute_param(pipe, cap, NULL);
  35.       std::vector<T> v(sz / sizeof(T));
  36.  
  37.       pipe->get_compute_param(pipe, cap, &v.front());
  38.       return v;
  39.    }
  40. }
  41.  
  42. device::device(clover::platform &platform, pipe_loader_device *ldev) :
  43.    platform(platform), ldev(ldev) {
  44.    pipe = pipe_loader_create_screen(ldev, PIPE_SEARCH_DIR);
  45.    if (!pipe || !pipe->get_param(pipe, PIPE_CAP_COMPUTE)) {
  46.       if (pipe)
  47.          pipe->destroy(pipe);
  48.       throw error(CL_INVALID_DEVICE);
  49.    }
  50. }
  51.  
  52. device::~device() {
  53.    if (pipe)
  54.       pipe->destroy(pipe);
  55.    if (ldev)
  56.       pipe_loader_release(&ldev, 1);
  57. }
  58.  
  59. bool
  60. device::operator==(const device &dev) const {
  61.    return this == &dev;
  62. }
  63.  
  64. cl_device_type
  65. device::type() const {
  66.    switch (ldev->type) {
  67.    case PIPE_LOADER_DEVICE_SOFTWARE:
  68.       return CL_DEVICE_TYPE_CPU;
  69.    case PIPE_LOADER_DEVICE_PCI:
  70.    case PIPE_LOADER_DEVICE_PLATFORM:
  71.       return CL_DEVICE_TYPE_GPU;
  72.    default:
  73.       unreachable("Unknown device type.");
  74.    }
  75. }
  76.  
  77. cl_uint
  78. device::vendor_id() const {
  79.    switch (ldev->type) {
  80.    case PIPE_LOADER_DEVICE_SOFTWARE:
  81.    case PIPE_LOADER_DEVICE_PLATFORM:
  82.       return 0;
  83.    case PIPE_LOADER_DEVICE_PCI:
  84.       return ldev->u.pci.vendor_id;
  85.    default:
  86.       unreachable("Unknown device type.");
  87.    }
  88. }
  89.  
  90. size_t
  91. device::max_images_read() const {
  92.    return PIPE_MAX_SHADER_RESOURCES;
  93. }
  94.  
  95. size_t
  96. device::max_images_write() const {
  97.    return PIPE_MAX_SHADER_RESOURCES;
  98. }
  99.  
  100. cl_uint
  101. device::max_image_levels_2d() const {
  102.    return pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
  103. }
  104.  
  105. cl_uint
  106. device::max_image_levels_3d() const {
  107.    return pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_3D_LEVELS);
  108. }
  109.  
  110. cl_uint
  111. device::max_samplers() const {
  112.    return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
  113.                                  PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS);
  114. }
  115.  
  116. cl_ulong
  117. device::max_mem_global() const {
  118.    return get_compute_param<uint64_t>(pipe,
  119.                                       PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE)[0];
  120. }
  121.  
  122. cl_ulong
  123. device::max_mem_local() const {
  124.    return get_compute_param<uint64_t>(pipe,
  125.                                       PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE)[0];
  126. }
  127.  
  128. cl_ulong
  129. device::max_mem_input() const {
  130.    return get_compute_param<uint64_t>(pipe,
  131.                                       PIPE_COMPUTE_CAP_MAX_INPUT_SIZE)[0];
  132. }
  133.  
  134. cl_ulong
  135. device::max_const_buffer_size() const {
  136.    return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
  137.                                  PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE);
  138. }
  139.  
  140. cl_uint
  141. device::max_const_buffers() const {
  142.    return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
  143.                                  PIPE_SHADER_CAP_MAX_CONST_BUFFERS);
  144. }
  145.  
  146. size_t
  147. device::max_threads_per_block() const {
  148.    return get_compute_param<uint64_t>(
  149.       pipe, PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK)[0];
  150. }
  151.  
  152. cl_ulong
  153. device::max_mem_alloc_size() const {
  154.    return get_compute_param<uint64_t>(pipe,
  155.                                       PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE)[0];
  156. }
  157.  
  158. cl_uint
  159. device::max_clock_frequency() const {
  160.    return get_compute_param<uint32_t>(pipe,
  161.                                       PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY)[0];
  162. }
  163.  
  164. cl_uint
  165. device::max_compute_units() const {
  166.    return get_compute_param<uint32_t>(pipe,
  167.                                       PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS)[0];
  168. }
  169.  
  170. bool
  171. device::image_support() const {
  172.    return get_compute_param<uint32_t>(pipe,
  173.                                       PIPE_COMPUTE_CAP_IMAGES_SUPPORTED)[0];
  174. }
  175.  
  176. bool
  177. device::has_doubles() const {
  178.    return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
  179.                                  PIPE_SHADER_CAP_DOUBLES);
  180. }
  181.  
  182. std::vector<size_t>
  183. device::max_block_size() const {
  184.    auto v = get_compute_param<uint64_t>(pipe, PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE);
  185.    return { v.begin(), v.end() };
  186. }
  187.  
  188. std::string
  189. device::device_name() const {
  190.    return pipe->get_name(pipe);
  191. }
  192.  
  193. std::string
  194. device::vendor_name() const {
  195.    return pipe->get_device_vendor(pipe);
  196. }
  197.  
  198. enum pipe_shader_ir
  199. device::ir_format() const {
  200.    return (enum pipe_shader_ir) pipe->get_shader_param(
  201.       pipe, PIPE_SHADER_COMPUTE, PIPE_SHADER_CAP_PREFERRED_IR);
  202. }
  203.  
  204. std::string
  205. device::ir_target() const {
  206.    std::vector<char> target = get_compute_param<char>(
  207.       pipe, PIPE_COMPUTE_CAP_IR_TARGET);
  208.    return { target.data() };
  209. }
  210.  
  211. enum pipe_endian
  212. device::endianness() const {
  213.    return (enum pipe_endian)pipe->get_param(pipe, PIPE_CAP_ENDIANNESS);
  214. }
  215.