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