st/dri: Use packed RGB formats
[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 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_IMAGES;
93 }
94
95 size_t
96 device::max_images_write() const {
97 return PIPE_MAX_SHADER_IMAGES;
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 cl_uint
189 device::subgroup_size() const {
190 return get_compute_param<uint32_t>(pipe, PIPE_COMPUTE_CAP_SUBGROUP_SIZE)[0];
191 }
192
193 std::string
194 device::device_name() const {
195 return pipe->get_name(pipe);
196 }
197
198 std::string
199 device::vendor_name() const {
200 return pipe->get_device_vendor(pipe);
201 }
202
203 enum pipe_shader_ir
204 device::ir_format() const {
205 return (enum pipe_shader_ir) pipe->get_shader_param(
206 pipe, PIPE_SHADER_COMPUTE, PIPE_SHADER_CAP_PREFERRED_IR);
207 }
208
209 std::string
210 device::ir_target() const {
211 std::vector<char> target = get_compute_param<char>(
212 pipe, PIPE_COMPUTE_CAP_IR_TARGET);
213 return { target.data() };
214 }
215
216 enum pipe_endian
217 device::endianness() const {
218 return (enum pipe_endian)pipe->get_param(pipe, PIPE_CAP_ENDIANNESS);
219 }