• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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