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