clover: Don't erase build info of devices not being built
[mesa.git] / src / gallium / state_trackers / clover / core / device.cpp
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
27 using namespace clover;
28
29 namespace {
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
59 cl_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
72 cl_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->u.pci.vendor_id;
79 default:
80 assert(0);
81 return 0;
82 }
83 }
84
85 size_t
86 _cl_device_id::max_images_read() const {
87 return PIPE_MAX_SHADER_RESOURCES;
88 }
89
90 size_t
91 _cl_device_id::max_images_write() const {
92 return PIPE_MAX_SHADER_RESOURCES;
93 }
94
95 cl_uint
96 _cl_device_id::max_image_levels_2d() const {
97 return pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
98 }
99
100 cl_uint
101 _cl_device_id::max_image_levels_3d() const {
102 return pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_3D_LEVELS);
103 }
104
105 cl_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
111 cl_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
117 cl_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
123 cl_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
129 cl_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
135 cl_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
141 size_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
147 cl_ulong
148 _cl_device_id::max_mem_alloc_size() const {
149 return get_compute_param<uint64_t>(pipe,
150 PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE)[0];
151 }
152
153 std::vector<size_t>
154 _cl_device_id::max_block_size() const {
155 auto v = get_compute_param<uint64_t>(pipe, PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE);
156 return { v.begin(), v.end() };
157 }
158
159 std::string
160 _cl_device_id::device_name() const {
161 return pipe->get_name(pipe);
162 }
163
164 std::string
165 _cl_device_id::vendor_name() const {
166 return pipe->get_vendor(pipe);
167 }
168
169 enum pipe_shader_ir
170 _cl_device_id::ir_format() const {
171 return (enum pipe_shader_ir) pipe->get_shader_param(pipe,
172 PIPE_SHADER_COMPUTE,
173 PIPE_SHADER_CAP_PREFERRED_IR);
174 }
175
176 std::string
177 _cl_device_id::ir_target() const {
178 std::vector<char> target = get_compute_param<char>(pipe,
179 PIPE_COMPUTE_CAP_IR_TARGET);
180 return { target.data() };
181 }
182
183 device_registry::device_registry() {
184 int n = pipe_loader_probe(NULL, 0);
185 std::vector<pipe_loader_device *> ldevs(n);
186
187 pipe_loader_probe(&ldevs.front(), n);
188
189 for (pipe_loader_device *ldev : ldevs) {
190 try {
191 devs.emplace_back(ldev);
192 } catch (error &) {}
193 }
194 }