• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _VKTPIPELINEUNIQUERANDOMITERATOR_HPP
2 #define _VKTPIPELINEUNIQUERANDOMITERATOR_HPP
3 /*------------------------------------------------------------------------
4  * Vulkan Conformance Tests
5  * ------------------------
6  *
7  * Copyright (c) 2015 The Khronos Group Inc.
8  * Copyright (c) 2015 Imagination Technologies Ltd.
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 Iterator over a unique sequence of items
25  *//*--------------------------------------------------------------------*/
26 
27 #include "tcuDefs.hpp"
28 #include "deRandom.hpp"
29 #include <set>
30 #include <vector>
31 
32 namespace vkt
33 {
34 namespace pipeline
35 {
36 
37 template <typename T>
38 class UniqueRandomIterator
39 {
40 public:
41 							UniqueRandomIterator	(deUint32 numItems, deUint32 numValues, int seed);
~UniqueRandomIterator(void)42 	virtual					~UniqueRandomIterator	(void) {}
43 	bool					hasNext					(void) const;
44 	T						next					(void);
45 	void					reset					(void);
46 
47 protected:
48 	virtual T				getIndexedValue			(deUint32 index) = 0;
49 
50 private:
51 	std::vector<deUint32>	m_indices;
52 	size_t					m_currentIndex;
53 };
54 
55 template <typename T>
UniqueRandomIterator(deUint32 numItems,deUint32 numValues,int seed)56 UniqueRandomIterator<T>::UniqueRandomIterator (deUint32 numItems, deUint32 numValues, int seed)
57 {
58 	de::Random rnd(seed);
59 
60 	DE_ASSERT(numItems <= numValues);
61 
62 	if (numItems == numValues)
63 	{
64 		// Fast way to populate the index sequence
65 		m_indices = std::vector<deUint32>(numItems);
66 
67 		for (deUint32 itemNdx = 0; itemNdx < numItems; itemNdx++)
68 			m_indices[itemNdx] = itemNdx;
69 	}
70 	else
71 	{
72 		std::set<deUint32> uniqueIndices;
73 
74 		// Populate set with "numItems" unique values between 0 and numValues - 1
75 		while (uniqueIndices.size() < numItems)
76 			uniqueIndices.insert(rnd.getUint32() % numValues);
77 
78 		// Copy set into index sequence
79 		m_indices = std::vector<deUint32>(uniqueIndices.begin(), uniqueIndices.end());
80 	}
81 
82 	// Scramble the indices
83 	rnd.shuffle(m_indices.begin(), m_indices.end());
84 
85 	reset();
86 }
87 
88 template <typename T>
hasNext(void) const89 bool UniqueRandomIterator<T>::hasNext (void) const
90 {
91 	return m_currentIndex < m_indices.size();
92 }
93 
94 template <typename T>
next(void)95 T UniqueRandomIterator<T>::next (void)
96 {
97 	DE_ASSERT(m_currentIndex < m_indices.size());
98 
99 	return getIndexedValue(m_indices[m_currentIndex++]);
100 }
101 
102 template <typename T>
reset(void)103 void UniqueRandomIterator<T>::reset (void)
104 {
105 	m_currentIndex = 0;
106 }
107 
108 } // pipeline
109 } // vkt
110 
111 #endif // _VKTPIPELINEUNIQUERANDOMITERATOR_HPP
112