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> struct tc;
45 template<class Key, class... Ignored>
46 struct tc<std::tuple<Key, Ignored...>> {
47 typedef std::tuple<Key, Ignored...> T;
operator ()vkt::api::u::tc48 bool operator()(const T& l, const T& r) const
49 { return std::get<0>(l) < std::get<0>(r); }
50 };
51
52 template<class Flag, class Bit, class... Ignored>
53 struct BitsSet : public std::set<std::tuple<Bit, Ignored...>, tc<std::tuple<Bit, Ignored...>>>
54 {
55 typedef Bit bit_type;
56 typedef Flag flag_type;
57 typedef std::tuple<Bit, Ignored...> value_type;
58 typedef std::set<value_type, tc<value_type>> base;
59 typedef typename base::const_iterator const_iterator;
BitsSetvkt::api::u::BitsSet60 BitsSet(std::initializer_list<value_type> list) : base(list) {}
BitsSetvkt::api::u::BitsSet61 BitsSet(BitsSet&& other) : base(std::forward<BitsSet>(other)) {}
BitsSetvkt::api::u::BitsSet62 BitsSet(const BitsSet& other) : base(other) {}
63 BitsSet() = default;
operator =vkt::api::u::BitsSet64 BitsSet& operator=(const BitsSet& other) {
65 base::operator=(other);
66 return *this;
67 }
operator =vkt::api::u::BitsSet68 BitsSet& operator=(BitsSet&& other) {
69 base::operator=(std::forward<BitsSet>(other));
70 return *this;
71 }
operator Flagvkt::api::u::BitsSet72 operator Flag() const {
73 Flag flag = static_cast<Flag>(0);
74 for (const auto& bit : *this)
75 flag |= std::get<0>(bit);
76 return flag;
77 }
operator ()vkt::api::u::BitsSet78 Flag operator()() const {
79 return static_cast<Flag>(*this);
80 }
containsvkt::api::u::BitsSet81 bool contains(const Bit& bit) const {
82 for (const auto& myBit : *this)
83 if (bit == std::get<0>(myBit)) return true;
84 return false;
85 }
anyvkt::api::u::BitsSet86 bool any(std::initializer_list<Bit> bits) const {
87 for (auto i = bits.begin(); i != bits.end(); ++i)
88 if (contains(*i)) return true;
89 return false;
90 }
allvkt::api::u::BitsSet91 bool all(std::initializer_list<Bit> bits) const {
92 for (auto i = bits.begin(); i != bits.end(); ++i)
93 if (!contains(*i)) return false;
94 return true;
95 }
containsvkt::api::u::BitsSet96 bool contains(const value_type& bit) const {
97 return contains(std::get<0>(bit));
98 }
findvkt::api::u::BitsSet99 const_iterator find(const Bit& bit) const {
100 auto end = std::end(*this);
101 for (auto i = std::begin(*this); i != end; ++i)
102 if (bit == std::get<0>(*i))
103 return i;
104 return end;
105 }
findvkt::api::u::BitsSet106 const_iterator find(const value_type& bit) const {
107 return find(std::get<0>(bit));
108 }
getvkt::api::u::BitsSet109 const value_type& get(const Bit& bit) const {
110 auto search = find(bit);
111 DE_ASSERT(search != std::end(*this));
112 return *search;
113 }
extractvkt::api::u::BitsSet114 static Bit extract(const value_type& bit) {
115 return std::get<0>(bit);
116 }
117 template<size_t Index, class TypeAt>
selectvkt::api::u::BitsSet118 BitsSet select(const TypeAt& typeAtIndex) const {
119 static_assert(std::is_same<TypeAt, typename std::tuple_element<Index, value_type>::type>::value, "");
120 BitsSet result;
121 for (const auto& bit : *this) {
122 if (typeAtIndex == std::get<Index>(bit))
123 result.insert(bit);
124 }
125 return result;
126 }
makeSharedvkt::api::u::BitsSet127 de::SharedPtr<BitsSet> makeShared() const {
128 return de::SharedPtr<BitsSet>(new BitsSet(*this));
129 }
makeSharedvkt::api::u::BitsSet130 static de::SharedPtr<BitsSet> makeShared(const value_type& bit) {
131 return de::SharedPtr<BitsSet>(new BitsSet({bit}));
132 }
makeSharedvkt::api::u::BitsSet133 static de::SharedPtr<BitsSet> makeShared(BitsSet&& src) {
134 return de::SharedPtr<BitsSet>(new BitsSet(std::move(src)));
135 }
136 };
137
138 template<class Flag, class Bits, class... Ignored>
mergeFlags(const std::vector<Flag> & flags1,const std::vector<BitsSet<Flag,Bits,Ignored...>> & flags2)139 std::vector<Flag> mergeFlags
140 (
141 const std::vector<Flag>& flags1,
142 const std::vector<BitsSet<Flag, Bits, Ignored...>>& flags2
143 )
144 {
145 std::vector<Flag> result;
146 if (!flags1.empty() && !flags2.empty()) {
147 for (const auto& flag1 : flags1) {
148 for (const auto& flag2 : flags2)
149 result.emplace_back(flag1 | flag2);
150 }
151 }
152 else if (flags2.empty()) {
153 result = flags1;
154 }
155 else if (flags1.empty()) {
156 for (const auto& flag2 : flags2)
157 result.emplace_back(flag2);
158 }
159 return result;
160 }
161
162 template<class Flag, class Bits, class... Ignored>
mergeFlags(std::vector<BitsSet<Flag,Bits,Ignored...>> & inout,const std::vector<BitsSet<Flag,Bits,Ignored...>> & flags)163 void mergeFlags
164 (
165 std::vector<BitsSet<Flag, Bits, Ignored...>>& inout,
166 const std::vector<BitsSet<Flag, Bits, Ignored...>>& flags
167 )
168 {
169 if (inout.empty())
170 inout.insert(inout.end(), flags.begin(), flags.end());
171 else {
172 for (auto& bits1: inout) {
173 for (const auto& bits2 : flags)
174 bits1.insert(bits2.begin(), bits2.end());
175 }
176 }
177 }
178
179 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)180 void combine
181 (
182 std::vector<BitsSet<Flag, Bit, Ignored...>>& result,
183 const BitsSet<Flag, Bit, Ignored...>& bits,
184 std::vector<Flag>& hints
185 )
186 {
187 const Flag flag = bits();
188 if (bits.empty() || hints.end() != std::find(hints.begin(), hints.end(), flag)) return;
189 hints.emplace_back(flag);
190 result.emplace_back(bits);
191 for (deUint32 b = 0; b < bits.size(); ++b) {
192 BitsSet<Flag, Bit, Ignored...> tmp(bits);
193 tmp.erase(std::next(tmp.begin(), b));
194 combine(result, tmp, hints);
195 }
196 }
197
198 } // u
199 } // api
200 } // vkt
201
202 #endif // _VKTAPIBUFFERMEMORYREQUIREMENTSTESTSUTILS_HPP
203