resolve merge conflicts of 297d0b5c to deqp-dev
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineUniqueRandomIterator.hpp
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);
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>
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>
89 bool UniqueRandomIterator<T>::hasNext (void) const
90 {
91         return m_currentIndex < m_indices.size();
92 }
93
94 template <typename T>
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>
103 void UniqueRandomIterator<T>::reset (void)
104 {
105         m_currentIndex = 0;
106 }
107
108 } // pipeline
109 } // vkt
110
111 #endif // _VKTPIPELINEUNIQUERANDOMITERATOR_HPP