Home | History | Annotate | Download | only in pipeline
      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