1 #ifndef _VKTAPIBUFFERMEMORYREQUIREMENTSTESTSUTILS_HPP
2 #define _VKTAPIBUFFERMEMORYREQUIREMENTSTESTSUTILS_HPP
3 /*------------------------------------------------------------------------
4 * Vulkan Conformance Tests
5 * ------------------------
6 *
7 * Copyright (c) 2021 The Khronos Group Inc.
8 * Copyright (c) 2016 The Android Open Source Project
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 *
22 *//*!
23 * \file
24 * \brief Utilities for vktApiMemoryRequirementsTests.
25 *//*--------------------------------------------------------------------*/
26
27 #include "deDefs.h"
28 #include "deSharedPtr.hpp"
29
30 #include <initializer_list>
31 #include <set>
32 #include <tuple>
33 #include <type_traits>
34 #include <utility>
35 #include <vector>
36
37 namespace vkt
38 {
39 namespace api
40 {
41 namespace u
42 {
43
44 template <class>
45 struct tc;
46 template <class Key, class... Ignored>
47 struct tc<std::tuple<Key, Ignored...>>
48 {
49 typedef std::tuple<Key, Ignored...> T;
operator ()vkt::api::u::tc50 bool operator()(const T &l, const T &r) const
51 {
52 return std::get<0>(l) < std::get<0>(r);
53 }
54 };
55
56 template <class Flag, class Bit, class... Ignored>
57 struct BitsSet : public std::set<std::tuple<Bit, Ignored...>, tc<std::tuple<Bit, Ignored...>>>
58 {
59 typedef Bit bit_type;
60 typedef Flag flag_type;
61 typedef std::tuple<Bit, Ignored...> value_type;
62 typedef std::set<value_type, tc<value_type>> base;
63 typedef typename base::const_iterator const_iterator;
BitsSetvkt::api::u::BitsSet64 BitsSet(std::initializer_list<value_type> list) : base(list)
65 {
66 }
BitsSetvkt::api::u::BitsSet67 BitsSet(BitsSet &&other) : base(std::forward<BitsSet>(other))
68 {
69 }
BitsSetvkt::api::u::BitsSet70 BitsSet(const BitsSet &other) : base(other)
71 {
72 }
73 BitsSet() = default;
operator =vkt::api::u::BitsSet74 BitsSet &operator=(const BitsSet &other)
75 {
76 base::operator=(other);
77 return *this;
78 }
operator =vkt::api::u::BitsSet79 BitsSet &operator=(BitsSet &&other)
80 {
81 base::operator=(std::forward<BitsSet>(other));
82 return *this;
83 }
operator Flagvkt::api::u::BitsSet84 operator Flag() const
85 {
86 Flag flag = static_cast<Flag>(0);
87 for (const auto &bit : *this)
88 flag |= std::get<0>(bit);
89 return flag;
90 }
operator ()vkt::api::u::BitsSet91 Flag operator()() const
92 {
93 return static_cast<Flag>(*this);
94 }
containsvkt::api::u::BitsSet95 bool contains(const Bit &bit) const
96 {
97 for (const auto &myBit : *this)
98 if (bit == std::get<0>(myBit))
99 return true;
100 return false;
101 }
anyvkt::api::u::BitsSet102 bool any(std::initializer_list<Bit> bits) const
103 {
104 for (auto i = bits.begin(); i != bits.end(); ++i)
105 if (contains(*i))
106 return true;
107 return false;
108 }
allvkt::api::u::BitsSet109 bool all(std::initializer_list<Bit> bits) const
110 {
111 for (auto i = bits.begin(); i != bits.end(); ++i)
112 if (!contains(*i))
113 return false;
114 return true;
115 }
containsvkt::api::u::BitsSet116 bool contains(const value_type &bit) const
117 {
118 return contains(std::get<0>(bit));
119 }
findvkt::api::u::BitsSet120 const_iterator find(const Bit &bit) const
121 {
122 auto end = std::end(*this);
123 for (auto i = std::begin(*this); i != end; ++i)
124 if (bit == std::get<0>(*i))
125 return i;
126 return end;
127 }
findvkt::api::u::BitsSet128 const_iterator find(const value_type &bit) const
129 {
130 return find(std::get<0>(bit));
131 }
getvkt::api::u::BitsSet132 const value_type &get(const Bit &bit) const
133 {
134 auto search = find(bit);
135 DE_ASSERT(search != std::end(*this));
136 return *search;
137 }
extractvkt::api::u::BitsSet138 static Bit extract(const value_type &bit)
139 {
140 return std::get<0>(bit);
141 }
142 template <size_t Index, class TypeAt>
selectvkt::api::u::BitsSet143 BitsSet select(const TypeAt &typeAtIndex) const
144 {
145 static_assert(std::is_same<TypeAt, typename std::tuple_element<Index, value_type>::type>::value, "");
146 BitsSet result;
147 for (const auto &bit : *this)
148 {
149 if (typeAtIndex == std::get<Index>(bit))
150 result.insert(bit);
151 }
152 return result;
153 }
makeSharedvkt::api::u::BitsSet154 de::SharedPtr<BitsSet> makeShared() const
155 {
156 return de::SharedPtr<BitsSet>(new BitsSet(*this));
157 }
makeSharedvkt::api::u::BitsSet158 static de::SharedPtr<BitsSet> makeShared(const value_type &bit)
159 {
160 return de::SharedPtr<BitsSet>(new BitsSet({bit}));
161 }
makeSharedvkt::api::u::BitsSet162 static de::SharedPtr<BitsSet> makeShared(BitsSet &&src)
163 {
164 return de::SharedPtr<BitsSet>(new BitsSet(std::move(src)));
165 }
166 };
167
168 template <class Flag, class Bits, class... Ignored>
mergeFlags(const std::vector<Flag> & flags1,const std::vector<BitsSet<Flag,Bits,Ignored...>> & flags2)169 std::vector<Flag> mergeFlags(const std::vector<Flag> &flags1,
170 const std::vector<BitsSet<Flag, Bits, Ignored...>> &flags2)
171 {
172 std::vector<Flag> result;
173 if (!flags1.empty() && !flags2.empty())
174 {
175 for (const auto &flag1 : flags1)
176 {
177 for (const auto &flag2 : flags2)
178 result.emplace_back(flag1 | flag2);
179 }
180 }
181 else if (flags2.empty())
182 {
183 result = flags1;
184 }
185 else if (flags1.empty())
186 {
187 for (const auto &flag2 : flags2)
188 result.emplace_back(flag2);
189 }
190 return result;
191 }
192
193 template <class Flag, class Bits, class... Ignored>
mergeFlags(std::vector<BitsSet<Flag,Bits,Ignored...>> & inout,const std::vector<BitsSet<Flag,Bits,Ignored...>> & flags)194 void mergeFlags(std::vector<BitsSet<Flag, Bits, Ignored...>> &inout,
195 const std::vector<BitsSet<Flag, Bits, Ignored...>> &flags)
196 {
197 if (inout.empty())
198 inout.insert(inout.end(), flags.begin(), flags.end());
199 else
200 {
201 for (auto &bits1 : inout)
202 {
203 for (const auto &bits2 : flags)
204 bits1.insert(bits2.begin(), bits2.end());
205 }
206 }
207 }
208
209 template <class Flag, class Bit, class... Ignored>
combine(std::vector<BitsSet<Flag,Bit,Ignored...>> & result,const BitsSet<Flag,Bit,Ignored...> & bits,std::vector<Flag> & hints)210 void combine(std::vector<BitsSet<Flag, Bit, Ignored...>> &result, const BitsSet<Flag, Bit, Ignored...> &bits,
211 std::vector<Flag> &hints)
212 {
213 const Flag flag = bits();
214 if (bits.empty() || hints.end() != std::find(hints.begin(), hints.end(), flag))
215 return;
216 hints.emplace_back(flag);
217 result.emplace_back(bits);
218 for (uint32_t b = 0; b < bits.size(); ++b)
219 {
220 BitsSet<Flag, Bit, Ignored...> tmp(bits);
221 tmp.erase(std::next(tmp.begin(), b));
222 combine(result, tmp, hints);
223 }
224 }
225
226 } // namespace u
227 } // namespace api
228 } // namespace vkt
229
230 #endif // _VKTAPIBUFFERMEMORYREQUIREMENTSTESTSUTILS_HPP
231