Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/clover/core/property.hpp
4572 views
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
typename std::enable_if<!std::is_convertible<T, S>::value, S>::type
203
as() const {
204
static_assert(sizeof(S) <= sizeof(T), "Ensure type fits in property list");
205
return reinterpret_cast<S>(x);
206
}
207
208
template<typename S>
209
typename std::enable_if<std::is_convertible<T, S>::value, S>::type
210
as() const {
211
return static_cast<S>(x);
212
}
213
214
private:
215
T x;
216
};
217
218
template<typename D>
219
using property_list = std::map<D, property_element<D>>;
220
221
struct property_list_tag;
222
223
///
224
/// Create a clover::property_list object from a zero-terminated
225
/// CL property list.
226
///
227
template<typename T, typename D,
228
typename = typename std::enable_if<
229
std::is_same<T, property_list_tag>::value>::type>
230
property_list<D>
231
obj(const D *d_props) {
232
property_list<D> props;
233
234
while (d_props && *d_props) {
235
auto key = *d_props++;
236
auto value = *d_props++;
237
238
if (props.count(key))
239
throw error(CL_INVALID_PROPERTY);
240
241
props.insert({ key, value });
242
}
243
244
return props;
245
}
246
247
///
248
/// Create a zero-terminated CL property list from a
249
/// clover::property_list object.
250
///
251
template<typename D>
252
std::vector<D>
253
desc(const property_list<D> &props) {
254
std::vector<D> d_props;
255
256
for (auto &prop : props) {
257
d_props.push_back(prop.first);
258
d_props.push_back(prop.second.template as<D>());
259
}
260
261
d_props.push_back(0);
262
263
return d_props;
264
}
265
}
266
267
#endif
268
269