Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5564 | serge | 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 |
||
32 | std::vector |
||
33 | get_compute_param(pipe_screen *pipe, pipe_compute_cap cap) { |
||
34 | int sz = pipe->get_compute_param(pipe, cap, NULL); |
||
35 | std::vector |
||
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 |
||
119 | PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE)[0]; |
||
120 | } |
||
121 | |||
122 | cl_ulong |
||
123 | device::max_mem_local() const { |
||
124 | return get_compute_param |
||
125 | PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE)[0]; |
||
126 | } |
||
127 | |||
128 | cl_ulong |
||
129 | device::max_mem_input() const { |
||
130 | return get_compute_param |
||
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 |
||
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 |
||
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 |
||
161 | PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY)[0]; |
||
162 | } |
||
163 | |||
164 | cl_uint |
||
165 | device::max_compute_units() const { |
||
166 | return get_compute_param |
||
167 | PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS)[0]; |
||
168 | } |
||
169 | |||
170 | bool |
||
171 | device::image_support() const { |
||
172 | return get_compute_param |
||
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 |
||
183 | device::max_block_size() const { |
||
184 | auto v = get_compute_param |
||
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 |
||
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 | } |