device.cpp revision 5c9bccc97e9fb0776f2ca5bb57e55116a7efb43b
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 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20// SOFTWARE.
21//
22
23#include "core/device.hpp"
24#include "pipe/p_screen.h"
25#include "pipe/p_state.h"
26
27using namespace clover;
28
29namespace {
30   template<typename T>
31   std::vector<T>
32   get_compute_param(pipe_screen *pipe, pipe_compute_cap cap) {
33      int sz = pipe->get_compute_param(pipe, cap, NULL);
34      std::vector<T> v(sz / sizeof(T));
35
36      pipe->get_compute_param(pipe, cap, &v.front());
37      return v;
38   }
39}
40
41_cl_device_id::_cl_device_id(pipe_loader_device *ldev) : ldev(ldev) {
42   pipe = pipe_loader_create_screen(ldev, PIPE_SEARCH_DIR);
43   if (!pipe || !pipe->get_param(pipe, PIPE_CAP_COMPUTE))
44      throw error(CL_INVALID_DEVICE);
45}
46
47_cl_device_id::_cl_device_id(_cl_device_id &&dev) : pipe(dev.pipe), ldev(dev.ldev) {
48   dev.ldev = NULL;
49   dev.pipe = NULL;
50}
51
52_cl_device_id::~_cl_device_id() {
53   if (pipe)
54      pipe->destroy(pipe);
55   if (ldev)
56      pipe_loader_release(&ldev, 1);
57}
58
59cl_device_type
60_cl_device_id::type() const {
61   switch (ldev->type) {
62   case PIPE_LOADER_DEVICE_SOFTWARE:
63      return CL_DEVICE_TYPE_CPU;
64   case PIPE_LOADER_DEVICE_PCI:
65      return CL_DEVICE_TYPE_GPU;
66   default:
67      assert(0);
68      return 0;
69   }
70}
71
72cl_uint
73_cl_device_id::vendor_id() const {
74   switch (ldev->type) {
75   case PIPE_LOADER_DEVICE_SOFTWARE:
76      return 0;
77   case PIPE_LOADER_DEVICE_PCI:
78      return ldev->pci.vendor_id;
79   default:
80      assert(0);
81      return 0;
82   }
83}
84
85size_t
86_cl_device_id::max_images_read() const {
87   return PIPE_MAX_SHADER_RESOURCES;
88}
89
90size_t
91_cl_device_id::max_images_write() const {
92   return PIPE_MAX_SHADER_RESOURCES;
93}
94
95cl_uint
96_cl_device_id::max_image_levels_2d() const {
97   return pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
98}
99
100cl_uint
101_cl_device_id::max_image_levels_3d() const {
102   return pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_3D_LEVELS);
103}
104
105cl_uint
106_cl_device_id::max_samplers() const {
107   return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
108                                 PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS);
109}
110
111cl_ulong
112_cl_device_id::max_mem_global() const {
113   return get_compute_param<uint64_t>(pipe,
114                                      PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE)[0];
115}
116
117cl_ulong
118_cl_device_id::max_mem_local() const {
119   return get_compute_param<uint64_t>(pipe,
120                                      PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE)[0];
121}
122
123cl_ulong
124_cl_device_id::max_mem_input() const {
125   return get_compute_param<uint64_t>(pipe,
126                                      PIPE_COMPUTE_CAP_MAX_INPUT_SIZE)[0];
127}
128
129cl_ulong
130_cl_device_id::max_const_buffer_size() const {
131   return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
132                                 PIPE_SHADER_CAP_MAX_CONSTS) * 16;
133}
134
135cl_uint
136_cl_device_id::max_const_buffers() const {
137   return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
138                                 PIPE_SHADER_CAP_MAX_CONST_BUFFERS);
139}
140
141size_t
142_cl_device_id::max_threads_per_block() const {
143   return get_compute_param<uint64_t>(
144      pipe, PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK)[0];
145}
146
147std::vector<size_t>
148_cl_device_id::max_block_size() const {
149   return get_compute_param<uint64_t>(pipe, PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE);
150}
151
152std::string
153_cl_device_id::device_name() const {
154   return pipe->get_name(pipe);
155}
156
157std::string
158_cl_device_id::vendor_name() const {
159   return pipe->get_vendor(pipe);
160}
161
162std::string
163_cl_device_id::ir_target() const {
164   switch (pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE,
165                                  PIPE_SHADER_CAP_PREFERRED_IR)) {
166   case PIPE_SHADER_IR_TGSI:
167      return "tgsi";
168   default:
169      assert(0);
170      return "";
171   }
172}
173
174device_registry::device_registry() {
175   int n = pipe_loader_probe(NULL, 0);
176   std::vector<pipe_loader_device *> ldevs(n);
177
178   pipe_loader_probe(&ldevs.front(), n);
179
180   for (pipe_loader_device *ldev : ldevs) {
181      try {
182         devs.emplace_back(ldev);
183      } catch (error &) {}
184   }
185}
186