gallium: add PIPE_CAP_RESOURCE_FROM_USER_MEMORY_COMPUTE_ONLY
[mesa.git] / src / gallium / frontends / clover / core / property.hpp
1 //
2 // Copyright 2013 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 #ifndef CLOVER_CORE_PROPERTY_HPP
24 #define CLOVER_CORE_PROPERTY_HPP
25
26 #include <map>
27
28 #include "util/range.hpp"
29 #include "util/algorithm.hpp"
30
31 namespace clover {
32 class property_buffer;
33
34 namespace detail {
35 template<typename T>
36 class property_scalar {
37 public:
38 property_scalar(property_buffer &buf) : buf(buf) {
39 }
40
41 inline property_scalar &
42 operator=(const T &x);
43
44 private:
45 property_buffer &buf;
46 };
47
48 template<typename T>
49 class property_vector {
50 public:
51 property_vector(property_buffer &buf) : buf(buf) {
52 }
53
54 template<typename S>
55 inline property_vector &
56 operator=(const S &v);
57
58 private:
59 property_buffer &buf;
60 };
61
62 template<typename T>
63 class property_matrix {
64 public:
65 property_matrix(property_buffer &buf) : buf(buf) {
66 }
67
68 template<typename S>
69 inline property_matrix &
70 operator=(const S &v);
71
72 private:
73 property_buffer &buf;
74 };
75
76 class property_string {
77 public:
78 property_string(property_buffer &buf) : buf(buf) {
79 }
80
81 inline property_string &
82 operator=(const std::string &v);
83
84 private:
85 property_buffer &buf;
86 };
87 };
88
89 ///
90 /// Return value buffer used by the CL property query functions.
91 ///
92 class property_buffer {
93 public:
94 property_buffer(void *r_buf, size_t size, size_t *r_size) :
95 r_buf(r_buf), size(size), r_size(r_size) {
96 }
97
98 template<typename T>
99 detail::property_scalar<T>
100 as_scalar() {
101 return { *this };
102 }
103
104 template<typename T>
105 detail::property_vector<T>
106 as_vector() {
107 return { *this };
108 }
109
110 template<typename T>
111 detail::property_matrix<T>
112 as_matrix() {
113 return { *this };
114 }
115
116 detail::property_string
117 as_string() {
118 return { *this };
119 }
120
121 template<typename T>
122 iterator_range<T *>
123 allocate(size_t n) {
124 if (r_buf && size < n * sizeof(T))
125 throw error(CL_INVALID_VALUE);
126
127 if (r_size)
128 *r_size = n * sizeof(T);
129
130 if (r_buf)
131 return range((T *)r_buf, n);
132 else
133 return { };
134 }
135
136 private:
137 void *const r_buf;
138 const size_t size;
139 size_t *const r_size;
140 };
141
142 namespace detail {
143 template<typename T>
144 inline property_scalar<T> &
145 property_scalar<T>::operator=(const T &x) {
146 auto r = buf.allocate<T>(1);
147
148 if (!r.empty())
149 r.front() = x;
150
151 return *this;
152 }
153
154 template<typename T>
155 template<typename S>
156 inline property_vector<T> &
157 property_vector<T>::operator=(const S &v) {
158 auto r = buf.allocate<T>(v.size());
159
160 if (!r.empty())
161 copy(v, r.begin());
162
163 return *this;
164 }
165
166 template<typename T>
167 template<typename S>
168 inline property_matrix<T> &
169 property_matrix<T>::operator=(const S &v) {
170 auto r = buf.allocate<T *>(v.size());
171
172 if (!r.empty())
173 for_each([](typename S::value_type src, T *dst) {
174 if (dst)
175 copy(src, dst);
176 }, v, r);
177
178 return *this;
179 }
180
181 inline property_string &
182 property_string::operator=(const std::string &v) {
183 auto r = buf.allocate<char>(v.size() + 1);
184
185 if (!r.empty())
186 copy(range(v.begin(), r.size()), r.begin());
187
188 return *this;
189 }
190 };
191
192 template<typename T>
193 class property_element {
194 public:
195 property_element() : x() {
196 }
197
198 property_element(T x) : x(x) {
199 }
200
201 template<typename S>
202 S
203 as() const {
204 assert(sizeof(S) <= sizeof(T));
205 return reinterpret_cast<S>(x);
206 }
207
208 private:
209 T x;
210 };
211
212 template<typename D>
213 using property_list = std::map<D, property_element<D>>;
214
215 struct property_list_tag;
216
217 ///
218 /// Create a clover::property_list object from a zero-terminated
219 /// CL property list.
220 ///
221 template<typename T, typename D,
222 typename = typename std::enable_if<
223 std::is_same<T, property_list_tag>::value>::type>
224 property_list<D>
225 obj(const D *d_props) {
226 property_list<D> props;
227
228 while (d_props && *d_props) {
229 auto key = *d_props++;
230 auto value = *d_props++;
231
232 if (props.count(key))
233 throw error(CL_INVALID_PROPERTY);
234
235 props.insert({ key, value });
236 }
237
238 return props;
239 }
240
241 ///
242 /// Create a zero-terminated CL property list from a
243 /// clover::property_list object.
244 ///
245 template<typename D>
246 std::vector<D>
247 desc(const property_list<D> &props) {
248 std::vector<D> d_props;
249
250 for (auto &prop : props) {
251 d_props.push_back(prop.first);
252 d_props.push_back(prop.second.template as<D>());
253 }
254
255 d_props.push_back(0);
256
257 return d_props;
258 }
259 }
260
261 #endif