1e5c31af7Sopenharmony_ci#ifndef _VKTPIPELINEUNIQUERANDOMITERATOR_HPP
2e5c31af7Sopenharmony_ci#define _VKTPIPELINEUNIQUERANDOMITERATOR_HPP
3e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------
4e5c31af7Sopenharmony_ci * Vulkan Conformance Tests
5e5c31af7Sopenharmony_ci * ------------------------
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Copyright (c) 2015 The Khronos Group Inc.
8e5c31af7Sopenharmony_ci * Copyright (c) 2015 Imagination Technologies Ltd.
9e5c31af7Sopenharmony_ci *
10e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
11e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
12e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
13e5c31af7Sopenharmony_ci *
14e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
15e5c31af7Sopenharmony_ci *
16e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
17e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
18e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
20e5c31af7Sopenharmony_ci * limitations under the License.
21e5c31af7Sopenharmony_ci *
22e5c31af7Sopenharmony_ci *//*!
23e5c31af7Sopenharmony_ci * \file
24e5c31af7Sopenharmony_ci * \brief Iterator over a unique sequence of items
25e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
26e5c31af7Sopenharmony_ci
27e5c31af7Sopenharmony_ci#include "tcuDefs.hpp"
28e5c31af7Sopenharmony_ci#include "deRandom.hpp"
29e5c31af7Sopenharmony_ci#include <set>
30e5c31af7Sopenharmony_ci#include <vector>
31e5c31af7Sopenharmony_ci
32e5c31af7Sopenharmony_cinamespace vkt
33e5c31af7Sopenharmony_ci{
34e5c31af7Sopenharmony_cinamespace pipeline
35e5c31af7Sopenharmony_ci{
36e5c31af7Sopenharmony_ci
37e5c31af7Sopenharmony_citemplate <typename T>
38e5c31af7Sopenharmony_ciclass UniqueRandomIterator
39e5c31af7Sopenharmony_ci{
40e5c31af7Sopenharmony_cipublic:
41e5c31af7Sopenharmony_ci							UniqueRandomIterator	(deUint32 numItems, deUint32 numValues, int seed);
42e5c31af7Sopenharmony_ci	virtual					~UniqueRandomIterator	(void) {}
43e5c31af7Sopenharmony_ci	bool					hasNext					(void) const;
44e5c31af7Sopenharmony_ci	T						next					(void);
45e5c31af7Sopenharmony_ci	void					reset					(void);
46e5c31af7Sopenharmony_ci
47e5c31af7Sopenharmony_ciprotected:
48e5c31af7Sopenharmony_ci	virtual T				getIndexedValue			(deUint32 index) = 0;
49e5c31af7Sopenharmony_ci
50e5c31af7Sopenharmony_ciprivate:
51e5c31af7Sopenharmony_ci	std::vector<deUint32>	m_indices;
52e5c31af7Sopenharmony_ci	size_t					m_currentIndex;
53e5c31af7Sopenharmony_ci};
54e5c31af7Sopenharmony_ci
55e5c31af7Sopenharmony_citemplate <typename T>
56e5c31af7Sopenharmony_ciUniqueRandomIterator<T>::UniqueRandomIterator (deUint32 numItems, deUint32 numValues, int seed)
57e5c31af7Sopenharmony_ci{
58e5c31af7Sopenharmony_ci	de::Random rnd(seed);
59e5c31af7Sopenharmony_ci
60e5c31af7Sopenharmony_ci	DE_ASSERT(numItems <= numValues);
61e5c31af7Sopenharmony_ci
62e5c31af7Sopenharmony_ci	if (numItems == numValues)
63e5c31af7Sopenharmony_ci	{
64e5c31af7Sopenharmony_ci		// Fast way to populate the index sequence
65e5c31af7Sopenharmony_ci		m_indices = std::vector<deUint32>(numItems);
66e5c31af7Sopenharmony_ci
67e5c31af7Sopenharmony_ci		for (deUint32 itemNdx = 0; itemNdx < numItems; itemNdx++)
68e5c31af7Sopenharmony_ci			m_indices[itemNdx] = itemNdx;
69e5c31af7Sopenharmony_ci	}
70e5c31af7Sopenharmony_ci	else
71e5c31af7Sopenharmony_ci	{
72e5c31af7Sopenharmony_ci		std::set<deUint32> uniqueIndices;
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_ci		// Populate set with "numItems" unique values between 0 and numValues - 1
75e5c31af7Sopenharmony_ci		while (uniqueIndices.size() < numItems)
76e5c31af7Sopenharmony_ci			uniqueIndices.insert(rnd.getUint32() % numValues);
77e5c31af7Sopenharmony_ci
78e5c31af7Sopenharmony_ci		// Copy set into index sequence
79e5c31af7Sopenharmony_ci		m_indices = std::vector<deUint32>(uniqueIndices.begin(), uniqueIndices.end());
80e5c31af7Sopenharmony_ci	}
81e5c31af7Sopenharmony_ci
82e5c31af7Sopenharmony_ci	// Scramble the indices
83e5c31af7Sopenharmony_ci	rnd.shuffle(m_indices.begin(), m_indices.end());
84e5c31af7Sopenharmony_ci
85e5c31af7Sopenharmony_ci	reset();
86e5c31af7Sopenharmony_ci}
87e5c31af7Sopenharmony_ci
88e5c31af7Sopenharmony_citemplate <typename T>
89e5c31af7Sopenharmony_cibool UniqueRandomIterator<T>::hasNext (void) const
90e5c31af7Sopenharmony_ci{
91e5c31af7Sopenharmony_ci	return m_currentIndex < m_indices.size();
92e5c31af7Sopenharmony_ci}
93e5c31af7Sopenharmony_ci
94e5c31af7Sopenharmony_citemplate <typename T>
95e5c31af7Sopenharmony_ciT UniqueRandomIterator<T>::next (void)
96e5c31af7Sopenharmony_ci{
97e5c31af7Sopenharmony_ci	DE_ASSERT(m_currentIndex < m_indices.size());
98e5c31af7Sopenharmony_ci
99e5c31af7Sopenharmony_ci	return getIndexedValue(m_indices[m_currentIndex++]);
100e5c31af7Sopenharmony_ci}
101e5c31af7Sopenharmony_ci
102e5c31af7Sopenharmony_citemplate <typename T>
103e5c31af7Sopenharmony_civoid UniqueRandomIterator<T>::reset (void)
104e5c31af7Sopenharmony_ci{
105e5c31af7Sopenharmony_ci	m_currentIndex = 0;
106e5c31af7Sopenharmony_ci}
107e5c31af7Sopenharmony_ci
108e5c31af7Sopenharmony_ci} // pipeline
109e5c31af7Sopenharmony_ci} // vkt
110e5c31af7Sopenharmony_ci
111e5c31af7Sopenharmony_ci#endif // _VKTPIPELINEUNIQUERANDOMITERATOR_HPP
112