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 112