Merge "Report tests using Draw*BaseVertex as NotSupported" am: f96636fdfa
[platform/upstream/VK-GL-CTS.git] / framework / delibs / decpp / deAppendList.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements C++ Base Library
3  * -----------------------------
4  *
5  * Copyright 2015 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Fast ordered append-only container
22  *//*--------------------------------------------------------------------*/
23
24 #include "deAppendList.hpp"
25 #include "deThread.hpp"
26 #include "deSpinBarrier.hpp"
27 #include "deSharedPtr.hpp"
28
29 #include <vector>
30 #include <algorithm>
31
32 namespace de
33 {
34
35 namespace
36 {
37
38 using std::vector;
39
40 struct TestElem
41 {
42         deUint32        threadNdx;
43         deUint32        elemNdx;
44
45         TestElem (deUint32 threadNdx_, deUint32 elemNdx_)
46                 : threadNdx     (threadNdx_)
47                 , elemNdx       (elemNdx_)
48         {}
49
50         TestElem (void)
51                 : threadNdx     (0)
52                 , elemNdx       (0)
53         {}
54 };
55
56 struct SharedState
57 {
58         deUint32                                numElements;
59         SpinBarrier                             barrier;
60         AppendList<TestElem>    testList;
61
62         SharedState (deUint32 numThreads, deUint32 numElements_, deUint32 numElementsHint)
63                 : numElements   (numElements_)
64                 , barrier               (numThreads)
65                 , testList              (numElementsHint)
66         {}
67 };
68
69 class TestThread : public Thread
70 {
71 public:
72         TestThread (SharedState* shared, deUint32 threadNdx)
73                 : m_shared              (shared)
74                 , m_threadNdx   (threadNdx)
75         {}
76
77         void run (void)
78         {
79                 const deUint32  syncPerElems    = 10000;
80
81                 for (deUint32 elemNdx = 0; elemNdx < m_shared->numElements; elemNdx++)
82                 {
83                         if (elemNdx % syncPerElems == 0)
84                                 m_shared->barrier.sync(SpinBarrier::WAIT_MODE_AUTO);
85
86                         m_shared->testList.append(TestElem(m_threadNdx, elemNdx));
87                 }
88         }
89
90 private:
91         SharedState* const      m_shared;
92         const deUint32          m_threadNdx;
93 };
94
95 typedef SharedPtr<TestThread> TestThreadSp;
96
97 void runAppendListTest (deUint32 numThreads, deUint32 numElements, deUint32 numElementsHint)
98 {
99         SharedState                             sharedState             (numThreads, numElements, numElementsHint);
100         vector<TestThreadSp>    threads                 (numThreads);
101
102         for (deUint32 threadNdx = 0; threadNdx < numThreads; ++threadNdx)
103         {
104                 threads[threadNdx] = TestThreadSp(new TestThread(&sharedState, threadNdx));
105                 threads[threadNdx]->start();
106         }
107
108         for (deUint32 threadNdx = 0; threadNdx < numThreads; ++threadNdx)
109                 threads[threadNdx]->join();
110
111         DE_TEST_ASSERT(sharedState.testList.size() == (size_t)numElements*(size_t)numThreads);
112
113         {
114                 vector<deUint32>        countByThread   (numThreads);
115
116                 std::fill(countByThread.begin(), countByThread.end(), 0);
117
118                 for (AppendList<TestElem>::const_iterator elemIter = sharedState.testList.begin();
119                          elemIter != sharedState.testList.end();
120                          ++elemIter)
121                 {
122                         const TestElem& elem    = *elemIter;
123
124                         DE_TEST_ASSERT(de::inBounds(elem.threadNdx, 0u, numThreads));
125                         DE_TEST_ASSERT(countByThread[elem.threadNdx] == elem.elemNdx);
126
127                         countByThread[elem.threadNdx] += 1;
128                 }
129
130                 for (deUint32 threadNdx = 0; threadNdx < numThreads; ++threadNdx)
131                         DE_TEST_ASSERT(countByThread[threadNdx] == numElements);
132         }
133 }
134
135 class ObjCountElem
136 {
137 public:
138         ObjCountElem (int* liveCount)
139                 : m_liveCount(liveCount)
140         {
141                 *m_liveCount += 1;
142         }
143
144         ~ObjCountElem (void)
145         {
146                 *m_liveCount -= 1;
147         }
148
149         ObjCountElem (const ObjCountElem& other)
150                 : m_liveCount(other.m_liveCount)
151         {
152                 *m_liveCount += 1;
153         }
154
155         ObjCountElem& operator= (const ObjCountElem& other)
156         {
157                 m_liveCount = other.m_liveCount;
158                 *m_liveCount += 1;
159                 return *this;
160         }
161
162 private:
163         int* m_liveCount;
164 };
165
166 void runClearTest (deUint32 numElements1, deUint32 numElements2, deUint32 numElementsHint)
167 {
168         int             liveCount       = 0;
169
170         {
171                 de::AppendList<ObjCountElem>    testList        (numElementsHint);
172
173                 for (deUint32 ndx = 0; ndx < numElements1; ++ndx)
174                         testList.append(ObjCountElem(&liveCount));
175
176                 DE_TEST_ASSERT(liveCount == (int)numElements1);
177
178                 testList.clear();
179
180                 DE_TEST_ASSERT(liveCount == 0);
181
182                 for (deUint32 ndx = 0; ndx < numElements2; ++ndx)
183                         testList.append(ObjCountElem(&liveCount));
184
185                 DE_TEST_ASSERT(liveCount == (int)numElements2);
186         }
187
188         DE_TEST_ASSERT(liveCount == 0);
189 }
190
191 } // anonymous
192
193 void AppendList_selfTest (void)
194 {
195         // Single-threaded
196         runAppendListTest(1, 1000, 500);
197         runAppendListTest(1, 1000, 2000);
198         runAppendListTest(1, 35, 1);
199
200         // Multi-threaded
201         runAppendListTest(2, 10000, 500);
202         runAppendListTest(2, 100, 10);
203
204         if (deGetNumAvailableLogicalCores() >= 4)
205         {
206                 runAppendListTest(4, 10000, 500);
207                 runAppendListTest(4, 100, 10);
208         }
209
210         // Dtor + clear()
211         runClearTest(1, 1, 1);
212         runClearTest(1, 2, 10);
213         runClearTest(50, 25, 10);
214         runClearTest(9, 50, 10);
215         runClearTest(10, 50, 10);
216         runClearTest(50, 9, 10);
217         runClearTest(50, 10, 10);
218 }
219
220 } // de