xref: /aosp_15_r20/external/deqp/modules/gles2/functional/es2fBufferWriteTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 2.0 Module
3*35238bceSAndroid Build Coastguard Worker  * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Buffer data upload tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es2fBufferWriteTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "es2fBufferTestUtil.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "deMemory.h"
29*35238bceSAndroid Build Coastguard Worker #include "deString.h"
30*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
33*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
35*35238bceSAndroid Build Coastguard Worker 
36*35238bceSAndroid Build Coastguard Worker #include <algorithm>
37*35238bceSAndroid Build Coastguard Worker #include <list>
38*35238bceSAndroid Build Coastguard Worker 
39*35238bceSAndroid Build Coastguard Worker using std::set;
40*35238bceSAndroid Build Coastguard Worker using std::string;
41*35238bceSAndroid Build Coastguard Worker using std::vector;
42*35238bceSAndroid Build Coastguard Worker using tcu::IVec2;
43*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
44*35238bceSAndroid Build Coastguard Worker 
45*35238bceSAndroid Build Coastguard Worker namespace deqp
46*35238bceSAndroid Build Coastguard Worker {
47*35238bceSAndroid Build Coastguard Worker namespace gles2
48*35238bceSAndroid Build Coastguard Worker {
49*35238bceSAndroid Build Coastguard Worker namespace Functional
50*35238bceSAndroid Build Coastguard Worker {
51*35238bceSAndroid Build Coastguard Worker 
52*35238bceSAndroid Build Coastguard Worker using namespace BufferTestUtil;
53*35238bceSAndroid Build Coastguard Worker 
54*35238bceSAndroid Build Coastguard Worker struct DataStoreSpec
55*35238bceSAndroid Build Coastguard Worker {
DataStoreSpecdeqp::gles2::Functional::DataStoreSpec56*35238bceSAndroid Build Coastguard Worker     DataStoreSpec(void) : target(0), usage(0), size(0)
57*35238bceSAndroid Build Coastguard Worker     {
58*35238bceSAndroid Build Coastguard Worker     }
59*35238bceSAndroid Build Coastguard Worker 
DataStoreSpecdeqp::gles2::Functional::DataStoreSpec60*35238bceSAndroid Build Coastguard Worker     DataStoreSpec(uint32_t target_, uint32_t usage_, int size_) : target(target_), usage(usage_), size(size_)
61*35238bceSAndroid Build Coastguard Worker     {
62*35238bceSAndroid Build Coastguard Worker     }
63*35238bceSAndroid Build Coastguard Worker 
64*35238bceSAndroid Build Coastguard Worker     uint32_t target;
65*35238bceSAndroid Build Coastguard Worker     uint32_t usage;
66*35238bceSAndroid Build Coastguard Worker     int size;
67*35238bceSAndroid Build Coastguard Worker };
68*35238bceSAndroid Build Coastguard Worker 
69*35238bceSAndroid Build Coastguard Worker struct DataStoreSpecVecBuilder
70*35238bceSAndroid Build Coastguard Worker {
71*35238bceSAndroid Build Coastguard Worker     std::vector<DataStoreSpec> &list;
72*35238bceSAndroid Build Coastguard Worker 
DataStoreSpecVecBuilderdeqp::gles2::Functional::DataStoreSpecVecBuilder73*35238bceSAndroid Build Coastguard Worker     DataStoreSpecVecBuilder(std::vector<DataStoreSpec> &list_) : list(list_)
74*35238bceSAndroid Build Coastguard Worker     {
75*35238bceSAndroid Build Coastguard Worker     }
76*35238bceSAndroid Build Coastguard Worker 
operator <<deqp::gles2::Functional::DataStoreSpecVecBuilder77*35238bceSAndroid Build Coastguard Worker     DataStoreSpecVecBuilder &operator<<(const DataStoreSpec &spec)
78*35238bceSAndroid Build Coastguard Worker     {
79*35238bceSAndroid Build Coastguard Worker         list.push_back(spec);
80*35238bceSAndroid Build Coastguard Worker         return *this;
81*35238bceSAndroid Build Coastguard Worker     }
82*35238bceSAndroid Build Coastguard Worker };
83*35238bceSAndroid Build Coastguard Worker 
84*35238bceSAndroid Build Coastguard Worker struct RangeVecBuilder
85*35238bceSAndroid Build Coastguard Worker {
86*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::IVec2> &list;
87*35238bceSAndroid Build Coastguard Worker 
RangeVecBuilderdeqp::gles2::Functional::RangeVecBuilder88*35238bceSAndroid Build Coastguard Worker     RangeVecBuilder(std::vector<tcu::IVec2> &list_) : list(list_)
89*35238bceSAndroid Build Coastguard Worker     {
90*35238bceSAndroid Build Coastguard Worker     }
91*35238bceSAndroid Build Coastguard Worker 
operator <<deqp::gles2::Functional::RangeVecBuilder92*35238bceSAndroid Build Coastguard Worker     RangeVecBuilder &operator<<(const tcu::IVec2 &vec)
93*35238bceSAndroid Build Coastguard Worker     {
94*35238bceSAndroid Build Coastguard Worker         list.push_back(vec);
95*35238bceSAndroid Build Coastguard Worker         return *this;
96*35238bceSAndroid Build Coastguard Worker     }
97*35238bceSAndroid Build Coastguard Worker };
98*35238bceSAndroid Build Coastguard Worker 
99*35238bceSAndroid Build Coastguard Worker template <typename Iterator>
isRangeListValid(Iterator begin,Iterator end)100*35238bceSAndroid Build Coastguard Worker static bool isRangeListValid(Iterator begin, Iterator end)
101*35238bceSAndroid Build Coastguard Worker {
102*35238bceSAndroid Build Coastguard Worker     if (begin != end)
103*35238bceSAndroid Build Coastguard Worker     {
104*35238bceSAndroid Build Coastguard Worker         // Fetch first.
105*35238bceSAndroid Build Coastguard Worker         tcu::IVec2 prev = *begin;
106*35238bceSAndroid Build Coastguard Worker         ++begin;
107*35238bceSAndroid Build Coastguard Worker 
108*35238bceSAndroid Build Coastguard Worker         for (; begin != end; ++begin)
109*35238bceSAndroid Build Coastguard Worker         {
110*35238bceSAndroid Build Coastguard Worker             tcu::IVec2 cur = *begin;
111*35238bceSAndroid Build Coastguard Worker             if (cur.x() <= prev.x() || cur.x() <= prev.x() + prev.y())
112*35238bceSAndroid Build Coastguard Worker                 return false;
113*35238bceSAndroid Build Coastguard Worker             prev = cur;
114*35238bceSAndroid Build Coastguard Worker         }
115*35238bceSAndroid Build Coastguard Worker     }
116*35238bceSAndroid Build Coastguard Worker 
117*35238bceSAndroid Build Coastguard Worker     return true;
118*35238bceSAndroid Build Coastguard Worker }
119*35238bceSAndroid Build Coastguard Worker 
rangesIntersect(const tcu::IVec2 & a,const tcu::IVec2 & b)120*35238bceSAndroid Build Coastguard Worker inline bool rangesIntersect(const tcu::IVec2 &a, const tcu::IVec2 &b)
121*35238bceSAndroid Build Coastguard Worker {
122*35238bceSAndroid Build Coastguard Worker     return de::inRange(a.x(), b.x(), b.x() + b.y()) || de::inRange(a.x() + a.y(), b.x(), b.x() + b.y()) ||
123*35238bceSAndroid Build Coastguard Worker            de::inRange(b.x(), a.x(), a.x() + a.y()) || de::inRange(b.x() + b.y(), a.x(), a.x() + a.y());
124*35238bceSAndroid Build Coastguard Worker }
125*35238bceSAndroid Build Coastguard Worker 
unionRanges(const tcu::IVec2 & a,const tcu::IVec2 & b)126*35238bceSAndroid Build Coastguard Worker inline tcu::IVec2 unionRanges(const tcu::IVec2 &a, const tcu::IVec2 &b)
127*35238bceSAndroid Build Coastguard Worker {
128*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(rangesIntersect(a, b));
129*35238bceSAndroid Build Coastguard Worker 
130*35238bceSAndroid Build Coastguard Worker     int start = de::min(a.x(), b.x());
131*35238bceSAndroid Build Coastguard Worker     int end   = de::max(a.x() + a.y(), b.x() + b.y());
132*35238bceSAndroid Build Coastguard Worker 
133*35238bceSAndroid Build Coastguard Worker     return tcu::IVec2(start, end - start);
134*35238bceSAndroid Build Coastguard Worker }
135*35238bceSAndroid Build Coastguard Worker 
136*35238bceSAndroid Build Coastguard Worker //! Updates range list (start, len) with a new range.
addRangeToList(const std::vector<tcu::IVec2> & oldList,const tcu::IVec2 & newRange)137*35238bceSAndroid Build Coastguard Worker std::vector<tcu::IVec2> addRangeToList(const std::vector<tcu::IVec2> &oldList, const tcu::IVec2 &newRange)
138*35238bceSAndroid Build Coastguard Worker {
139*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(newRange.y() > 0);
140*35238bceSAndroid Build Coastguard Worker 
141*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::IVec2> newList;
142*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::IVec2>::const_iterator oldListIter = oldList.begin();
143*35238bceSAndroid Build Coastguard Worker 
144*35238bceSAndroid Build Coastguard Worker     // Append ranges that end before the new range.
145*35238bceSAndroid Build Coastguard Worker     for (; oldListIter != oldList.end() && oldListIter->x() + oldListIter->y() < newRange.x(); ++oldListIter)
146*35238bceSAndroid Build Coastguard Worker         newList.push_back(*oldListIter);
147*35238bceSAndroid Build Coastguard Worker 
148*35238bceSAndroid Build Coastguard Worker     // Join any ranges that intersect new range
149*35238bceSAndroid Build Coastguard Worker     {
150*35238bceSAndroid Build Coastguard Worker         tcu::IVec2 curRange = newRange;
151*35238bceSAndroid Build Coastguard Worker         while (oldListIter != oldList.end() && rangesIntersect(curRange, *oldListIter))
152*35238bceSAndroid Build Coastguard Worker         {
153*35238bceSAndroid Build Coastguard Worker             curRange = unionRanges(curRange, *oldListIter);
154*35238bceSAndroid Build Coastguard Worker             ++oldListIter;
155*35238bceSAndroid Build Coastguard Worker         }
156*35238bceSAndroid Build Coastguard Worker 
157*35238bceSAndroid Build Coastguard Worker         newList.push_back(curRange);
158*35238bceSAndroid Build Coastguard Worker     }
159*35238bceSAndroid Build Coastguard Worker 
160*35238bceSAndroid Build Coastguard Worker     // Append remaining ranges.
161*35238bceSAndroid Build Coastguard Worker     for (; oldListIter != oldList.end(); oldListIter++)
162*35238bceSAndroid Build Coastguard Worker         newList.push_back(*oldListIter);
163*35238bceSAndroid Build Coastguard Worker 
164*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(isRangeListValid(newList.begin(), newList.end()));
165*35238bceSAndroid Build Coastguard Worker 
166*35238bceSAndroid Build Coastguard Worker     return newList;
167*35238bceSAndroid Build Coastguard Worker }
168*35238bceSAndroid Build Coastguard Worker 
169*35238bceSAndroid Build Coastguard Worker class BasicBufferDataCase : public BufferCase
170*35238bceSAndroid Build Coastguard Worker {
171*35238bceSAndroid Build Coastguard Worker public:
BasicBufferDataCase(Context & context,const char * name,const char * desc,uint32_t target,uint32_t usage,int size,VerifyType verify)172*35238bceSAndroid Build Coastguard Worker     BasicBufferDataCase(Context &context, const char *name, const char *desc, uint32_t target, uint32_t usage, int size,
173*35238bceSAndroid Build Coastguard Worker                         VerifyType verify)
174*35238bceSAndroid Build Coastguard Worker         : BufferCase(context, name, desc)
175*35238bceSAndroid Build Coastguard Worker         , m_target(target)
176*35238bceSAndroid Build Coastguard Worker         , m_usage(usage)
177*35238bceSAndroid Build Coastguard Worker         , m_size(size)
178*35238bceSAndroid Build Coastguard Worker         , m_verify(verify)
179*35238bceSAndroid Build Coastguard Worker     {
180*35238bceSAndroid Build Coastguard Worker     }
181*35238bceSAndroid Build Coastguard Worker 
iterate(void)182*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
183*35238bceSAndroid Build Coastguard Worker     {
184*35238bceSAndroid Build Coastguard Worker         const uint32_t dataSeed = deStringHash(getName()) ^ 0x125;
185*35238bceSAndroid Build Coastguard Worker         BufferVerifier verifier(m_context, m_verify);
186*35238bceSAndroid Build Coastguard Worker         ReferenceBuffer refBuf;
187*35238bceSAndroid Build Coastguard Worker         bool isOk = false;
188*35238bceSAndroid Build Coastguard Worker 
189*35238bceSAndroid Build Coastguard Worker         refBuf.setSize(m_size);
190*35238bceSAndroid Build Coastguard Worker         fillWithRandomBytes(refBuf.getPtr(), m_size, dataSeed);
191*35238bceSAndroid Build Coastguard Worker 
192*35238bceSAndroid Build Coastguard Worker         uint32_t buf = genBuffer();
193*35238bceSAndroid Build Coastguard Worker         glBindBuffer(m_target, buf);
194*35238bceSAndroid Build Coastguard Worker         glBufferData(m_target, m_size, refBuf.getPtr(), m_usage);
195*35238bceSAndroid Build Coastguard Worker 
196*35238bceSAndroid Build Coastguard Worker         checkError();
197*35238bceSAndroid Build Coastguard Worker 
198*35238bceSAndroid Build Coastguard Worker         isOk = verifier.verify(buf, refBuf.getPtr(), 0, m_size);
199*35238bceSAndroid Build Coastguard Worker 
200*35238bceSAndroid Build Coastguard Worker         deleteBuffer(buf);
201*35238bceSAndroid Build Coastguard Worker 
202*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
203*35238bceSAndroid Build Coastguard Worker                                 isOk ? "Pass" : "Buffer verification failed");
204*35238bceSAndroid Build Coastguard Worker         return STOP;
205*35238bceSAndroid Build Coastguard Worker     }
206*35238bceSAndroid Build Coastguard Worker 
207*35238bceSAndroid Build Coastguard Worker private:
208*35238bceSAndroid Build Coastguard Worker     uint32_t m_target;
209*35238bceSAndroid Build Coastguard Worker     uint32_t m_usage;
210*35238bceSAndroid Build Coastguard Worker     int m_size;
211*35238bceSAndroid Build Coastguard Worker     VerifyType m_verify;
212*35238bceSAndroid Build Coastguard Worker };
213*35238bceSAndroid Build Coastguard Worker 
214*35238bceSAndroid Build Coastguard Worker class RecreateBufferDataStoreCase : public BufferCase
215*35238bceSAndroid Build Coastguard Worker {
216*35238bceSAndroid Build Coastguard Worker public:
RecreateBufferDataStoreCase(Context & context,const char * name,const char * desc,const DataStoreSpec * specs,int numSpecs,VerifyType verify)217*35238bceSAndroid Build Coastguard Worker     RecreateBufferDataStoreCase(Context &context, const char *name, const char *desc, const DataStoreSpec *specs,
218*35238bceSAndroid Build Coastguard Worker                                 int numSpecs, VerifyType verify)
219*35238bceSAndroid Build Coastguard Worker         : BufferCase(context, name, desc)
220*35238bceSAndroid Build Coastguard Worker         , m_specs(specs, specs + numSpecs)
221*35238bceSAndroid Build Coastguard Worker         , m_verify(verify)
222*35238bceSAndroid Build Coastguard Worker     {
223*35238bceSAndroid Build Coastguard Worker     }
224*35238bceSAndroid Build Coastguard Worker 
iterate(void)225*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
226*35238bceSAndroid Build Coastguard Worker     {
227*35238bceSAndroid Build Coastguard Worker         const uint32_t baseSeed = deStringHash(getName()) ^ 0xbeef;
228*35238bceSAndroid Build Coastguard Worker         BufferVerifier verifier(m_context, m_verify);
229*35238bceSAndroid Build Coastguard Worker         ReferenceBuffer refBuf;
230*35238bceSAndroid Build Coastguard Worker         const uint32_t buf = genBuffer();
231*35238bceSAndroid Build Coastguard Worker 
232*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
233*35238bceSAndroid Build Coastguard Worker 
234*35238bceSAndroid Build Coastguard Worker         for (vector<DataStoreSpec>::const_iterator spec = m_specs.begin(); spec != m_specs.end(); spec++)
235*35238bceSAndroid Build Coastguard Worker         {
236*35238bceSAndroid Build Coastguard Worker             bool iterOk = false;
237*35238bceSAndroid Build Coastguard Worker 
238*35238bceSAndroid Build Coastguard Worker             refBuf.setSize(spec->size);
239*35238bceSAndroid Build Coastguard Worker             fillWithRandomBytes(refBuf.getPtr(), spec->size,
240*35238bceSAndroid Build Coastguard Worker                                 baseSeed ^ deInt32Hash(spec->size + spec->target + spec->usage));
241*35238bceSAndroid Build Coastguard Worker 
242*35238bceSAndroid Build Coastguard Worker             glBindBuffer(spec->target, buf);
243*35238bceSAndroid Build Coastguard Worker             glBufferData(spec->target, spec->size, refBuf.getPtr(), spec->usage);
244*35238bceSAndroid Build Coastguard Worker 
245*35238bceSAndroid Build Coastguard Worker             checkError();
246*35238bceSAndroid Build Coastguard Worker 
247*35238bceSAndroid Build Coastguard Worker             iterOk = verifier.verify(buf, refBuf.getPtr(), 0, spec->size);
248*35238bceSAndroid Build Coastguard Worker 
249*35238bceSAndroid Build Coastguard Worker             if (!iterOk)
250*35238bceSAndroid Build Coastguard Worker             {
251*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
252*35238bceSAndroid Build Coastguard Worker                 break;
253*35238bceSAndroid Build Coastguard Worker             }
254*35238bceSAndroid Build Coastguard Worker         }
255*35238bceSAndroid Build Coastguard Worker 
256*35238bceSAndroid Build Coastguard Worker         deleteBuffer(buf);
257*35238bceSAndroid Build Coastguard Worker         return STOP;
258*35238bceSAndroid Build Coastguard Worker     }
259*35238bceSAndroid Build Coastguard Worker 
260*35238bceSAndroid Build Coastguard Worker private:
261*35238bceSAndroid Build Coastguard Worker     std::vector<DataStoreSpec> m_specs;
262*35238bceSAndroid Build Coastguard Worker     VerifyType m_verify;
263*35238bceSAndroid Build Coastguard Worker };
264*35238bceSAndroid Build Coastguard Worker 
265*35238bceSAndroid Build Coastguard Worker class BasicBufferSubDataCase : public BufferCase
266*35238bceSAndroid Build Coastguard Worker {
267*35238bceSAndroid Build Coastguard Worker public:
BasicBufferSubDataCase(Context & context,const char * name,const char * desc,uint32_t target,uint32_t usage,int size,int subDataOffs,int subDataSize,VerifyType verify)268*35238bceSAndroid Build Coastguard Worker     BasicBufferSubDataCase(Context &context, const char *name, const char *desc, uint32_t target, uint32_t usage,
269*35238bceSAndroid Build Coastguard Worker                            int size, int subDataOffs, int subDataSize, VerifyType verify)
270*35238bceSAndroid Build Coastguard Worker         : BufferCase(context, name, desc)
271*35238bceSAndroid Build Coastguard Worker         , m_target(target)
272*35238bceSAndroid Build Coastguard Worker         , m_usage(usage)
273*35238bceSAndroid Build Coastguard Worker         , m_size(size)
274*35238bceSAndroid Build Coastguard Worker         , m_subDataOffs(subDataOffs)
275*35238bceSAndroid Build Coastguard Worker         , m_subDataSize(subDataSize)
276*35238bceSAndroid Build Coastguard Worker         , m_verify(verify)
277*35238bceSAndroid Build Coastguard Worker     {
278*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(de::inBounds(subDataOffs, 0, size) && de::inRange(subDataOffs + subDataSize, 0, size));
279*35238bceSAndroid Build Coastguard Worker     }
280*35238bceSAndroid Build Coastguard Worker 
iterate(void)281*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
282*35238bceSAndroid Build Coastguard Worker     {
283*35238bceSAndroid Build Coastguard Worker         const uint32_t dataSeed = deStringHash(getName());
284*35238bceSAndroid Build Coastguard Worker         BufferVerifier verifier(m_context, m_verify);
285*35238bceSAndroid Build Coastguard Worker         ReferenceBuffer refBuf;
286*35238bceSAndroid Build Coastguard Worker         bool isOk = false;
287*35238bceSAndroid Build Coastguard Worker 
288*35238bceSAndroid Build Coastguard Worker         refBuf.setSize(m_size);
289*35238bceSAndroid Build Coastguard Worker 
290*35238bceSAndroid Build Coastguard Worker         uint32_t buf = genBuffer();
291*35238bceSAndroid Build Coastguard Worker         glBindBuffer(m_target, buf);
292*35238bceSAndroid Build Coastguard Worker 
293*35238bceSAndroid Build Coastguard Worker         // Initialize with glBufferData()
294*35238bceSAndroid Build Coastguard Worker         fillWithRandomBytes(refBuf.getPtr(), m_size, dataSeed ^ 0x80354f);
295*35238bceSAndroid Build Coastguard Worker         glBufferData(m_target, m_size, refBuf.getPtr(), m_usage);
296*35238bceSAndroid Build Coastguard Worker         checkError();
297*35238bceSAndroid Build Coastguard Worker 
298*35238bceSAndroid Build Coastguard Worker         // Re-specify part of buffer
299*35238bceSAndroid Build Coastguard Worker         fillWithRandomBytes(refBuf.getPtr() + m_subDataOffs, m_subDataSize, dataSeed ^ 0xfac425c);
300*35238bceSAndroid Build Coastguard Worker         glBufferSubData(m_target, m_subDataOffs, m_subDataSize, refBuf.getPtr() + m_subDataOffs);
301*35238bceSAndroid Build Coastguard Worker 
302*35238bceSAndroid Build Coastguard Worker         isOk = verifier.verify(buf, refBuf.getPtr(), 0, m_size);
303*35238bceSAndroid Build Coastguard Worker 
304*35238bceSAndroid Build Coastguard Worker         deleteBuffer(buf);
305*35238bceSAndroid Build Coastguard Worker 
306*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
307*35238bceSAndroid Build Coastguard Worker                                 isOk ? "Pass" : "Buffer verification failed");
308*35238bceSAndroid Build Coastguard Worker         return STOP;
309*35238bceSAndroid Build Coastguard Worker     }
310*35238bceSAndroid Build Coastguard Worker 
311*35238bceSAndroid Build Coastguard Worker private:
312*35238bceSAndroid Build Coastguard Worker     uint32_t m_target;
313*35238bceSAndroid Build Coastguard Worker     uint32_t m_usage;
314*35238bceSAndroid Build Coastguard Worker     int m_size;
315*35238bceSAndroid Build Coastguard Worker     int m_subDataOffs;
316*35238bceSAndroid Build Coastguard Worker     int m_subDataSize;
317*35238bceSAndroid Build Coastguard Worker     VerifyType m_verify;
318*35238bceSAndroid Build Coastguard Worker };
319*35238bceSAndroid Build Coastguard Worker 
320*35238bceSAndroid Build Coastguard Worker class SubDataToUndefinedCase : public BufferCase
321*35238bceSAndroid Build Coastguard Worker {
322*35238bceSAndroid Build Coastguard Worker public:
SubDataToUndefinedCase(Context & context,const char * name,const char * desc,uint32_t target,uint32_t usage,int size,const tcu::IVec2 * ranges,int numRanges,VerifyType verify)323*35238bceSAndroid Build Coastguard Worker     SubDataToUndefinedCase(Context &context, const char *name, const char *desc, uint32_t target, uint32_t usage,
324*35238bceSAndroid Build Coastguard Worker                            int size, const tcu::IVec2 *ranges, int numRanges, VerifyType verify)
325*35238bceSAndroid Build Coastguard Worker         : BufferCase(context, name, desc)
326*35238bceSAndroid Build Coastguard Worker         , m_target(target)
327*35238bceSAndroid Build Coastguard Worker         , m_usage(usage)
328*35238bceSAndroid Build Coastguard Worker         , m_size(size)
329*35238bceSAndroid Build Coastguard Worker         , m_ranges(ranges, ranges + numRanges)
330*35238bceSAndroid Build Coastguard Worker         , m_verify(verify)
331*35238bceSAndroid Build Coastguard Worker     {
332*35238bceSAndroid Build Coastguard Worker     }
333*35238bceSAndroid Build Coastguard Worker 
iterate(void)334*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
335*35238bceSAndroid Build Coastguard Worker     {
336*35238bceSAndroid Build Coastguard Worker         const uint32_t dataSeed = deStringHash(getName());
337*35238bceSAndroid Build Coastguard Worker         BufferVerifier verifier(m_context, m_verify);
338*35238bceSAndroid Build Coastguard Worker         ReferenceBuffer refBuf;
339*35238bceSAndroid Build Coastguard Worker         bool isOk = true;
340*35238bceSAndroid Build Coastguard Worker         std::vector<tcu::IVec2> definedRanges;
341*35238bceSAndroid Build Coastguard Worker 
342*35238bceSAndroid Build Coastguard Worker         refBuf.setSize(m_size);
343*35238bceSAndroid Build Coastguard Worker 
344*35238bceSAndroid Build Coastguard Worker         uint32_t buf = genBuffer();
345*35238bceSAndroid Build Coastguard Worker         glBindBuffer(m_target, buf);
346*35238bceSAndroid Build Coastguard Worker 
347*35238bceSAndroid Build Coastguard Worker         // Initialize storage with glBufferData()
348*35238bceSAndroid Build Coastguard Worker         glBufferData(m_target, m_size, DE_NULL, m_usage);
349*35238bceSAndroid Build Coastguard Worker         checkError();
350*35238bceSAndroid Build Coastguard Worker 
351*35238bceSAndroid Build Coastguard Worker         // Fill specified ranges with glBufferSubData()
352*35238bceSAndroid Build Coastguard Worker         for (vector<tcu::IVec2>::const_iterator range = m_ranges.begin(); range != m_ranges.end(); range++)
353*35238bceSAndroid Build Coastguard Worker         {
354*35238bceSAndroid Build Coastguard Worker             fillWithRandomBytes(refBuf.getPtr() + range->x(), range->y(),
355*35238bceSAndroid Build Coastguard Worker                                 dataSeed ^ deInt32Hash(range->x() + range->y()));
356*35238bceSAndroid Build Coastguard Worker             glBufferSubData(m_target, range->x(), range->y(), refBuf.getPtr() + range->x());
357*35238bceSAndroid Build Coastguard Worker 
358*35238bceSAndroid Build Coastguard Worker             // Mark range as defined
359*35238bceSAndroid Build Coastguard Worker             definedRanges = addRangeToList(definedRanges, *range);
360*35238bceSAndroid Build Coastguard Worker         }
361*35238bceSAndroid Build Coastguard Worker 
362*35238bceSAndroid Build Coastguard Worker         // Verify defined parts
363*35238bceSAndroid Build Coastguard Worker         for (vector<tcu::IVec2>::const_iterator range = definedRanges.begin(); range != definedRanges.end(); range++)
364*35238bceSAndroid Build Coastguard Worker         {
365*35238bceSAndroid Build Coastguard Worker             if (!verifier.verify(buf, refBuf.getPtr(), range->x(), range->y()))
366*35238bceSAndroid Build Coastguard Worker                 isOk = false;
367*35238bceSAndroid Build Coastguard Worker         }
368*35238bceSAndroid Build Coastguard Worker 
369*35238bceSAndroid Build Coastguard Worker         deleteBuffer(buf);
370*35238bceSAndroid Build Coastguard Worker 
371*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
372*35238bceSAndroid Build Coastguard Worker                                 isOk ? "Pass" : "Buffer verification failed");
373*35238bceSAndroid Build Coastguard Worker         return STOP;
374*35238bceSAndroid Build Coastguard Worker     }
375*35238bceSAndroid Build Coastguard Worker 
376*35238bceSAndroid Build Coastguard Worker private:
377*35238bceSAndroid Build Coastguard Worker     uint32_t m_target;
378*35238bceSAndroid Build Coastguard Worker     uint32_t m_usage;
379*35238bceSAndroid Build Coastguard Worker     int m_size;
380*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::IVec2> m_ranges;
381*35238bceSAndroid Build Coastguard Worker     VerifyType m_verify;
382*35238bceSAndroid Build Coastguard Worker };
383*35238bceSAndroid Build Coastguard Worker 
384*35238bceSAndroid Build Coastguard Worker class RandomBufferWriteCase : public BufferCase
385*35238bceSAndroid Build Coastguard Worker {
386*35238bceSAndroid Build Coastguard Worker public:
RandomBufferWriteCase(Context & context,const char * name,const char * desc,uint32_t seed)387*35238bceSAndroid Build Coastguard Worker     RandomBufferWriteCase(Context &context, const char *name, const char *desc, uint32_t seed)
388*35238bceSAndroid Build Coastguard Worker         : BufferCase(context, name, desc)
389*35238bceSAndroid Build Coastguard Worker         , m_seed(seed)
390*35238bceSAndroid Build Coastguard Worker         , m_verifier(DE_NULL)
391*35238bceSAndroid Build Coastguard Worker         , m_buffer(0)
392*35238bceSAndroid Build Coastguard Worker         , m_curSize(0)
393*35238bceSAndroid Build Coastguard Worker         , m_iterNdx(0)
394*35238bceSAndroid Build Coastguard Worker     {
395*35238bceSAndroid Build Coastguard Worker     }
396*35238bceSAndroid Build Coastguard Worker 
~RandomBufferWriteCase(void)397*35238bceSAndroid Build Coastguard Worker     ~RandomBufferWriteCase(void)
398*35238bceSAndroid Build Coastguard Worker     {
399*35238bceSAndroid Build Coastguard Worker         delete m_verifier;
400*35238bceSAndroid Build Coastguard Worker     }
401*35238bceSAndroid Build Coastguard Worker 
init(void)402*35238bceSAndroid Build Coastguard Worker     void init(void)
403*35238bceSAndroid Build Coastguard Worker     {
404*35238bceSAndroid Build Coastguard Worker         BufferCase::init();
405*35238bceSAndroid Build Coastguard Worker 
406*35238bceSAndroid Build Coastguard Worker         m_iterNdx  = 0;
407*35238bceSAndroid Build Coastguard Worker         m_buffer   = genBuffer();
408*35238bceSAndroid Build Coastguard Worker         m_curSize  = 0;
409*35238bceSAndroid Build Coastguard Worker         m_verifier = new BufferVerifier(m_context, VERIFY_AS_VERTEX_ARRAY);
410*35238bceSAndroid Build Coastguard Worker 
411*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
412*35238bceSAndroid Build Coastguard Worker     }
413*35238bceSAndroid Build Coastguard Worker 
deinit(void)414*35238bceSAndroid Build Coastguard Worker     void deinit(void)
415*35238bceSAndroid Build Coastguard Worker     {
416*35238bceSAndroid Build Coastguard Worker         deleteBuffer(m_buffer);
417*35238bceSAndroid Build Coastguard Worker         m_refBuffer.setSize(0);
418*35238bceSAndroid Build Coastguard Worker 
419*35238bceSAndroid Build Coastguard Worker         delete m_verifier;
420*35238bceSAndroid Build Coastguard Worker         m_verifier = DE_NULL;
421*35238bceSAndroid Build Coastguard Worker 
422*35238bceSAndroid Build Coastguard Worker         BufferCase::deinit();
423*35238bceSAndroid Build Coastguard Worker     }
424*35238bceSAndroid Build Coastguard Worker 
iterate(void)425*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
426*35238bceSAndroid Build Coastguard Worker     {
427*35238bceSAndroid Build Coastguard Worker         // Parameters.
428*35238bceSAndroid Build Coastguard Worker         const int numIterations              = 5;
429*35238bceSAndroid Build Coastguard Worker         const int uploadsPerIteration        = 7;
430*35238bceSAndroid Build Coastguard Worker         const int minSize                    = 12;
431*35238bceSAndroid Build Coastguard Worker         const int maxSize                    = 32 * 1024;
432*35238bceSAndroid Build Coastguard Worker         const float respecifyProbability     = 0.07f;
433*35238bceSAndroid Build Coastguard Worker         const float respecifyDataProbability = 0.2f;
434*35238bceSAndroid Build Coastguard Worker 
435*35238bceSAndroid Build Coastguard Worker         static const uint32_t bufferTargets[] = {GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER};
436*35238bceSAndroid Build Coastguard Worker 
437*35238bceSAndroid Build Coastguard Worker         static const uint32_t usageHints[] = {
438*35238bceSAndroid Build Coastguard Worker             GL_STREAM_DRAW,
439*35238bceSAndroid Build Coastguard Worker             GL_STATIC_DRAW,
440*35238bceSAndroid Build Coastguard Worker             GL_DYNAMIC_DRAW,
441*35238bceSAndroid Build Coastguard Worker         };
442*35238bceSAndroid Build Coastguard Worker 
443*35238bceSAndroid Build Coastguard Worker         bool iterOk             = true;
444*35238bceSAndroid Build Coastguard Worker         uint32_t curBoundTarget = GL_NONE;
445*35238bceSAndroid Build Coastguard Worker         de::Random rnd(m_seed ^ deInt32Hash(m_iterNdx) ^ 0xacf92e);
446*35238bceSAndroid Build Coastguard Worker 
447*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Section(string("Iteration") + de::toString(m_iterNdx + 1),
448*35238bceSAndroid Build Coastguard Worker                                                string("Iteration ") + de::toString(m_iterNdx + 1) + " / " +
449*35238bceSAndroid Build Coastguard Worker                                                    de::toString(numIterations));
450*35238bceSAndroid Build Coastguard Worker 
451*35238bceSAndroid Build Coastguard Worker         for (int uploadNdx = 0; uploadNdx < uploadsPerIteration; uploadNdx++)
452*35238bceSAndroid Build Coastguard Worker         {
453*35238bceSAndroid Build Coastguard Worker             const uint32_t target = bufferTargets[rnd.getInt(0, DE_LENGTH_OF_ARRAY(bufferTargets) - 1)];
454*35238bceSAndroid Build Coastguard Worker             const bool respecify  = m_curSize == 0 || rnd.getFloat() < respecifyProbability;
455*35238bceSAndroid Build Coastguard Worker 
456*35238bceSAndroid Build Coastguard Worker             if (target != curBoundTarget)
457*35238bceSAndroid Build Coastguard Worker             {
458*35238bceSAndroid Build Coastguard Worker                 glBindBuffer(target, m_buffer);
459*35238bceSAndroid Build Coastguard Worker                 curBoundTarget = target;
460*35238bceSAndroid Build Coastguard Worker             }
461*35238bceSAndroid Build Coastguard Worker 
462*35238bceSAndroid Build Coastguard Worker             if (respecify)
463*35238bceSAndroid Build Coastguard Worker             {
464*35238bceSAndroid Build Coastguard Worker                 const int size          = rnd.getInt(minSize, maxSize);
465*35238bceSAndroid Build Coastguard Worker                 const uint32_t hint     = usageHints[rnd.getInt(0, DE_LENGTH_OF_ARRAY(usageHints) - 1)];
466*35238bceSAndroid Build Coastguard Worker                 const bool fillWithData = rnd.getFloat() < respecifyDataProbability;
467*35238bceSAndroid Build Coastguard Worker 
468*35238bceSAndroid Build Coastguard Worker                 m_refBuffer.setSize(size);
469*35238bceSAndroid Build Coastguard Worker                 if (fillWithData)
470*35238bceSAndroid Build Coastguard Worker                     fillWithRandomBytes(m_refBuffer.getPtr(), size, rnd.getUint32());
471*35238bceSAndroid Build Coastguard Worker 
472*35238bceSAndroid Build Coastguard Worker                 glBufferData(target, size, fillWithData ? m_refBuffer.getPtr() : DE_NULL, hint);
473*35238bceSAndroid Build Coastguard Worker 
474*35238bceSAndroid Build Coastguard Worker                 m_validRanges.clear();
475*35238bceSAndroid Build Coastguard Worker                 if (fillWithData)
476*35238bceSAndroid Build Coastguard Worker                     m_validRanges.push_back(tcu::IVec2(0, size));
477*35238bceSAndroid Build Coastguard Worker 
478*35238bceSAndroid Build Coastguard Worker                 m_curSize = size;
479*35238bceSAndroid Build Coastguard Worker             }
480*35238bceSAndroid Build Coastguard Worker             else
481*35238bceSAndroid Build Coastguard Worker             {
482*35238bceSAndroid Build Coastguard Worker                 // \note Non-uniform size distribution.
483*35238bceSAndroid Build Coastguard Worker                 const int size =
484*35238bceSAndroid Build Coastguard Worker                     de::clamp(deRoundFloatToInt32((float)m_curSize * deFloatPow(rnd.getFloat(0.0f, 0.7f), 3.0f)),
485*35238bceSAndroid Build Coastguard Worker                               minSize, m_curSize);
486*35238bceSAndroid Build Coastguard Worker                 const int offset = rnd.getInt(0, m_curSize - size);
487*35238bceSAndroid Build Coastguard Worker 
488*35238bceSAndroid Build Coastguard Worker                 fillWithRandomBytes(m_refBuffer.getPtr() + offset, size, rnd.getUint32());
489*35238bceSAndroid Build Coastguard Worker                 glBufferSubData(target, offset, size, m_refBuffer.getPtr() + offset);
490*35238bceSAndroid Build Coastguard Worker 
491*35238bceSAndroid Build Coastguard Worker                 m_validRanges = addRangeToList(m_validRanges, tcu::IVec2(offset, size));
492*35238bceSAndroid Build Coastguard Worker             }
493*35238bceSAndroid Build Coastguard Worker         }
494*35238bceSAndroid Build Coastguard Worker 
495*35238bceSAndroid Build Coastguard Worker         // Check error.
496*35238bceSAndroid Build Coastguard Worker         {
497*35238bceSAndroid Build Coastguard Worker             uint32_t err = glGetError();
498*35238bceSAndroid Build Coastguard Worker             if (err != GL_NO_ERROR)
499*35238bceSAndroid Build Coastguard Worker                 throw tcu::TestError(string("Got ") + glu::getErrorStr(err).toString());
500*35238bceSAndroid Build Coastguard Worker         }
501*35238bceSAndroid Build Coastguard Worker 
502*35238bceSAndroid Build Coastguard Worker         // Verify valid ranges.
503*35238bceSAndroid Build Coastguard Worker         for (vector<IVec2>::const_iterator range = m_validRanges.begin(); range != m_validRanges.end(); range++)
504*35238bceSAndroid Build Coastguard Worker         {
505*35238bceSAndroid Build Coastguard Worker             if (!m_verifier->verify(m_buffer, m_refBuffer.getPtr(), range->x(), range->y()))
506*35238bceSAndroid Build Coastguard Worker             {
507*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer verification failed");
508*35238bceSAndroid Build Coastguard Worker                 iterOk = false;
509*35238bceSAndroid Build Coastguard Worker                 break;
510*35238bceSAndroid Build Coastguard Worker             }
511*35238bceSAndroid Build Coastguard Worker         }
512*35238bceSAndroid Build Coastguard Worker 
513*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::EndSection;
514*35238bceSAndroid Build Coastguard Worker 
515*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(iterOk || m_testCtx.getTestResult() != QP_TEST_RESULT_PASS);
516*35238bceSAndroid Build Coastguard Worker 
517*35238bceSAndroid Build Coastguard Worker         m_iterNdx += 1;
518*35238bceSAndroid Build Coastguard Worker         return (iterOk && m_iterNdx < numIterations) ? CONTINUE : STOP;
519*35238bceSAndroid Build Coastguard Worker     }
520*35238bceSAndroid Build Coastguard Worker 
521*35238bceSAndroid Build Coastguard Worker private:
522*35238bceSAndroid Build Coastguard Worker     uint32_t m_seed;
523*35238bceSAndroid Build Coastguard Worker 
524*35238bceSAndroid Build Coastguard Worker     BufferVerifier *m_verifier;
525*35238bceSAndroid Build Coastguard Worker     uint32_t m_buffer;
526*35238bceSAndroid Build Coastguard Worker     ReferenceBuffer m_refBuffer;
527*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::IVec2> m_validRanges;
528*35238bceSAndroid Build Coastguard Worker     int m_curSize;
529*35238bceSAndroid Build Coastguard Worker     int m_iterNdx;
530*35238bceSAndroid Build Coastguard Worker };
531*35238bceSAndroid Build Coastguard Worker 
BufferWriteTests(Context & context)532*35238bceSAndroid Build Coastguard Worker BufferWriteTests::BufferWriteTests(Context &context) : TestCaseGroup(context, "write", "Buffer data upload tests")
533*35238bceSAndroid Build Coastguard Worker {
534*35238bceSAndroid Build Coastguard Worker }
535*35238bceSAndroid Build Coastguard Worker 
~BufferWriteTests(void)536*35238bceSAndroid Build Coastguard Worker BufferWriteTests::~BufferWriteTests(void)
537*35238bceSAndroid Build Coastguard Worker {
538*35238bceSAndroid Build Coastguard Worker }
539*35238bceSAndroid Build Coastguard Worker 
init(void)540*35238bceSAndroid Build Coastguard Worker void BufferWriteTests::init(void)
541*35238bceSAndroid Build Coastguard Worker {
542*35238bceSAndroid Build Coastguard Worker     static const uint32_t bufferTargets[] = {GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER};
543*35238bceSAndroid Build Coastguard Worker 
544*35238bceSAndroid Build Coastguard Worker     static const uint32_t usageHints[] = {GL_STREAM_DRAW, GL_STATIC_DRAW, GL_DYNAMIC_DRAW};
545*35238bceSAndroid Build Coastguard Worker 
546*35238bceSAndroid Build Coastguard Worker     static const struct
547*35238bceSAndroid Build Coastguard Worker     {
548*35238bceSAndroid Build Coastguard Worker         const char *name;
549*35238bceSAndroid Build Coastguard Worker         VerifyType verify;
550*35238bceSAndroid Build Coastguard Worker     } verifyTypes[] = {{"vertex_array", VERIFY_AS_VERTEX_ARRAY}, {"index_array", VERIFY_AS_INDEX_ARRAY}};
551*35238bceSAndroid Build Coastguard Worker 
552*35238bceSAndroid Build Coastguard Worker     // .basic
553*35238bceSAndroid Build Coastguard Worker     {
554*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const basicGroup =
555*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "basic", "Basic upload with glBufferData()");
556*35238bceSAndroid Build Coastguard Worker         addChild(basicGroup);
557*35238bceSAndroid Build Coastguard Worker 
558*35238bceSAndroid Build Coastguard Worker         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
559*35238bceSAndroid Build Coastguard Worker         {
560*35238bceSAndroid Build Coastguard Worker             for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usageHints); usageNdx++)
561*35238bceSAndroid Build Coastguard Worker             {
562*35238bceSAndroid Build Coastguard Worker                 const uint32_t target   = bufferTargets[targetNdx];
563*35238bceSAndroid Build Coastguard Worker                 const uint32_t usage    = usageHints[usageNdx];
564*35238bceSAndroid Build Coastguard Worker                 const int size          = 1020;
565*35238bceSAndroid Build Coastguard Worker                 const VerifyType verify = VERIFY_AS_VERTEX_ARRAY;
566*35238bceSAndroid Build Coastguard Worker                 const string name       = string(getBufferTargetName(target)) + "_" + getUsageHintName(usage);
567*35238bceSAndroid Build Coastguard Worker 
568*35238bceSAndroid Build Coastguard Worker                 basicGroup->addChild(new BasicBufferDataCase(m_context, name.c_str(), "", target, usage, size, verify));
569*35238bceSAndroid Build Coastguard Worker             }
570*35238bceSAndroid Build Coastguard Worker         }
571*35238bceSAndroid Build Coastguard Worker     }
572*35238bceSAndroid Build Coastguard Worker 
573*35238bceSAndroid Build Coastguard Worker     // .use
574*35238bceSAndroid Build Coastguard Worker     {
575*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const useGroup = new tcu::TestCaseGroup(m_testCtx, "use", "Buffer uses");
576*35238bceSAndroid Build Coastguard Worker         addChild(useGroup);
577*35238bceSAndroid Build Coastguard Worker 
578*35238bceSAndroid Build Coastguard Worker         for (int verifyNdx = 0; verifyNdx < DE_LENGTH_OF_ARRAY(verifyTypes); verifyNdx++)
579*35238bceSAndroid Build Coastguard Worker         {
580*35238bceSAndroid Build Coastguard Worker             tcu::TestCaseGroup *const verifyGroup = new tcu::TestCaseGroup(m_testCtx, verifyTypes[verifyNdx].name, "");
581*35238bceSAndroid Build Coastguard Worker             useGroup->addChild(verifyGroup);
582*35238bceSAndroid Build Coastguard Worker 
583*35238bceSAndroid Build Coastguard Worker             for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
584*35238bceSAndroid Build Coastguard Worker             {
585*35238bceSAndroid Build Coastguard Worker                 const uint32_t target   = bufferTargets[targetNdx];
586*35238bceSAndroid Build Coastguard Worker                 const uint32_t usage    = GL_STATIC_DRAW;
587*35238bceSAndroid Build Coastguard Worker                 const int size          = 763;
588*35238bceSAndroid Build Coastguard Worker                 const VerifyType verify = verifyTypes[verifyNdx].verify;
589*35238bceSAndroid Build Coastguard Worker                 const string name       = getBufferTargetName(target);
590*35238bceSAndroid Build Coastguard Worker 
591*35238bceSAndroid Build Coastguard Worker                 verifyGroup->addChild(
592*35238bceSAndroid Build Coastguard Worker                     new BasicBufferDataCase(m_context, name.c_str(), "", target, usage, size, verify));
593*35238bceSAndroid Build Coastguard Worker             }
594*35238bceSAndroid Build Coastguard Worker         }
595*35238bceSAndroid Build Coastguard Worker     }
596*35238bceSAndroid Build Coastguard Worker 
597*35238bceSAndroid Build Coastguard Worker     // .recreate_store
598*35238bceSAndroid Build Coastguard Worker     {
599*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const recreateStoreGroup =
600*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "recreate_store", "Data store recreate using glBufferData()");
601*35238bceSAndroid Build Coastguard Worker         addChild(recreateStoreGroup);
602*35238bceSAndroid Build Coastguard Worker 
603*35238bceSAndroid Build Coastguard Worker #define RECREATE_STORE_CASE(NAME, DESC, SPECLIST)                                                                 \
604*35238bceSAndroid Build Coastguard Worker     do                                                                                                            \
605*35238bceSAndroid Build Coastguard Worker     {                                                                                                             \
606*35238bceSAndroid Build Coastguard Worker         std::vector<DataStoreSpec> specs;                                                                         \
607*35238bceSAndroid Build Coastguard Worker         DataStoreSpecVecBuilder builder(specs);                                                                   \
608*35238bceSAndroid Build Coastguard Worker         builder SPECLIST;                                                                                         \
609*35238bceSAndroid Build Coastguard Worker         recreateStoreGroup->addChild(new RecreateBufferDataStoreCase(m_context, #NAME, DESC, &specs[0],           \
610*35238bceSAndroid Build Coastguard Worker                                                                      (int)specs.size(), VERIFY_AS_VERTEX_ARRAY)); \
611*35238bceSAndroid Build Coastguard Worker     } while (false)
612*35238bceSAndroid Build Coastguard Worker 
613*35238bceSAndroid Build Coastguard Worker         RECREATE_STORE_CASE(identical_1, "Recreate with identical parameters",
614*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ARRAY_BUFFER, GL_STATIC_DRAW, 996)
615*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ARRAY_BUFFER, GL_STATIC_DRAW, 996)
616*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ARRAY_BUFFER, GL_STATIC_DRAW, 996));
617*35238bceSAndroid Build Coastguard Worker 
618*35238bceSAndroid Build Coastguard Worker         RECREATE_STORE_CASE(identical_2, "Recreate with identical parameters",
619*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, 72)
620*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, 72)
621*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, 72));
622*35238bceSAndroid Build Coastguard Worker 
623*35238bceSAndroid Build Coastguard Worker         RECREATE_STORE_CASE(different_target_1, "Recreate with different target",
624*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ARRAY_BUFFER, GL_STATIC_DRAW, 504)
625*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, 504));
626*35238bceSAndroid Build Coastguard Worker 
627*35238bceSAndroid Build Coastguard Worker         RECREATE_STORE_CASE(different_target_2, "Recreate with different target",
628*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, 716)
629*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ARRAY_BUFFER, GL_STATIC_DRAW, 716)
630*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, 716));
631*35238bceSAndroid Build Coastguard Worker 
632*35238bceSAndroid Build Coastguard Worker         RECREATE_STORE_CASE(different_usage, "Recreate with different usage",
633*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ARRAY_BUFFER, GL_STREAM_DRAW, 1644)
634*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW, 1644)
635*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ARRAY_BUFFER, GL_STATIC_DRAW, 1644)
636*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ARRAY_BUFFER, GL_STREAM_DRAW, 1644));
637*35238bceSAndroid Build Coastguard Worker 
638*35238bceSAndroid Build Coastguard Worker         RECREATE_STORE_CASE(different_size, "Recreate with different size",
639*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ARRAY_BUFFER, GL_STREAM_DRAW, 1024)
640*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ARRAY_BUFFER, GL_STREAM_DRAW, 12)
641*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ARRAY_BUFFER, GL_STREAM_DRAW, 3327)
642*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ARRAY_BUFFER, GL_STREAM_DRAW, 92)
643*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ARRAY_BUFFER, GL_STREAM_DRAW, 12379)
644*35238bceSAndroid Build Coastguard Worker                             << DataStoreSpec(GL_ARRAY_BUFFER, GL_STREAM_DRAW, 571));
645*35238bceSAndroid Build Coastguard Worker 
646*35238bceSAndroid Build Coastguard Worker #undef RECREATE_STORE_CASE
647*35238bceSAndroid Build Coastguard Worker 
648*35238bceSAndroid Build Coastguard Worker         // Random cases.
649*35238bceSAndroid Build Coastguard Worker         {
650*35238bceSAndroid Build Coastguard Worker             const int numRandomCases    = 4;
651*35238bceSAndroid Build Coastguard Worker             const int numUploadsPerCase = 10;
652*35238bceSAndroid Build Coastguard Worker             const int minSize           = 12;
653*35238bceSAndroid Build Coastguard Worker             const int maxSize           = 65536;
654*35238bceSAndroid Build Coastguard Worker             const VerifyType verify     = VERIFY_AS_VERTEX_ARRAY;
655*35238bceSAndroid Build Coastguard Worker             de::Random rnd(23921);
656*35238bceSAndroid Build Coastguard Worker 
657*35238bceSAndroid Build Coastguard Worker             for (int caseNdx = 0; caseNdx < numRandomCases; caseNdx++)
658*35238bceSAndroid Build Coastguard Worker             {
659*35238bceSAndroid Build Coastguard Worker                 vector<DataStoreSpec> specs(numUploadsPerCase);
660*35238bceSAndroid Build Coastguard Worker 
661*35238bceSAndroid Build Coastguard Worker                 for (vector<DataStoreSpec>::iterator spec = specs.begin(); spec != specs.end(); spec++)
662*35238bceSAndroid Build Coastguard Worker                 {
663*35238bceSAndroid Build Coastguard Worker                     spec->target = bufferTargets[rnd.getInt(0, DE_LENGTH_OF_ARRAY(bufferTargets) - 1)];
664*35238bceSAndroid Build Coastguard Worker                     spec->usage  = usageHints[rnd.getInt(0, DE_LENGTH_OF_ARRAY(usageHints) - 1)];
665*35238bceSAndroid Build Coastguard Worker                     spec->size   = rnd.getInt(minSize, maxSize);
666*35238bceSAndroid Build Coastguard Worker                 }
667*35238bceSAndroid Build Coastguard Worker 
668*35238bceSAndroid Build Coastguard Worker                 recreateStoreGroup->addChild(
669*35238bceSAndroid Build Coastguard Worker                     new RecreateBufferDataStoreCase(m_context, (string("random_") + de::toString(caseNdx + 1)).c_str(),
670*35238bceSAndroid Build Coastguard Worker                                                     "", &specs[0], (int)specs.size(), verify));
671*35238bceSAndroid Build Coastguard Worker             }
672*35238bceSAndroid Build Coastguard Worker         }
673*35238bceSAndroid Build Coastguard Worker     }
674*35238bceSAndroid Build Coastguard Worker 
675*35238bceSAndroid Build Coastguard Worker     // .basic_subdata
676*35238bceSAndroid Build Coastguard Worker     {
677*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const basicGroup =
678*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "basic_subdata", "Basic glBufferSubData() usage");
679*35238bceSAndroid Build Coastguard Worker         addChild(basicGroup);
680*35238bceSAndroid Build Coastguard Worker 
681*35238bceSAndroid Build Coastguard Worker         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
682*35238bceSAndroid Build Coastguard Worker         {
683*35238bceSAndroid Build Coastguard Worker             for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usageHints); usageNdx++)
684*35238bceSAndroid Build Coastguard Worker             {
685*35238bceSAndroid Build Coastguard Worker                 const uint32_t target   = bufferTargets[targetNdx];
686*35238bceSAndroid Build Coastguard Worker                 const uint32_t usage    = usageHints[usageNdx];
687*35238bceSAndroid Build Coastguard Worker                 const int size          = 1020;
688*35238bceSAndroid Build Coastguard Worker                 const VerifyType verify = VERIFY_AS_VERTEX_ARRAY;
689*35238bceSAndroid Build Coastguard Worker                 const string name       = string(getBufferTargetName(target)) + "_" + getUsageHintName(usage);
690*35238bceSAndroid Build Coastguard Worker 
691*35238bceSAndroid Build Coastguard Worker                 basicGroup->addChild(new BasicBufferDataCase(m_context, name.c_str(), "", target, usage, size, verify));
692*35238bceSAndroid Build Coastguard Worker             }
693*35238bceSAndroid Build Coastguard Worker         }
694*35238bceSAndroid Build Coastguard Worker     }
695*35238bceSAndroid Build Coastguard Worker 
696*35238bceSAndroid Build Coastguard Worker     // .partial_specify
697*35238bceSAndroid Build Coastguard Worker     {
698*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const partialSpecifyGroup = new tcu::TestCaseGroup(
699*35238bceSAndroid Build Coastguard Worker             m_testCtx, "partial_specify", "Partial buffer data specification with glBufferSubData()");
700*35238bceSAndroid Build Coastguard Worker         addChild(partialSpecifyGroup);
701*35238bceSAndroid Build Coastguard Worker 
702*35238bceSAndroid Build Coastguard Worker #define PARTIAL_SPECIFY_CASE(NAME, DESC, TARGET, USAGE, SIZE, RANGELIST)                                           \
703*35238bceSAndroid Build Coastguard Worker     do                                                                                                             \
704*35238bceSAndroid Build Coastguard Worker     {                                                                                                              \
705*35238bceSAndroid Build Coastguard Worker         std::vector<tcu::IVec2> ranges;                                                                            \
706*35238bceSAndroid Build Coastguard Worker         RangeVecBuilder builder(ranges);                                                                           \
707*35238bceSAndroid Build Coastguard Worker         builder RANGELIST;                                                                                         \
708*35238bceSAndroid Build Coastguard Worker         partialSpecifyGroup->addChild(new SubDataToUndefinedCase(                                                  \
709*35238bceSAndroid Build Coastguard Worker             m_context, #NAME, DESC, TARGET, USAGE, SIZE, &ranges[0], (int)ranges.size(), VERIFY_AS_VERTEX_ARRAY)); \
710*35238bceSAndroid Build Coastguard Worker     } while (false)
711*35238bceSAndroid Build Coastguard Worker 
712*35238bceSAndroid Build Coastguard Worker         PARTIAL_SPECIFY_CASE(whole_1, "Whole buffer specification with single glBufferSubData()", GL_ARRAY_BUFFER,
713*35238bceSAndroid Build Coastguard Worker                              GL_STATIC_DRAW, 996, << IVec2(0, 996));
714*35238bceSAndroid Build Coastguard Worker         PARTIAL_SPECIFY_CASE(whole_2, "Whole buffer specification with two calls", GL_ELEMENT_ARRAY_BUFFER,
715*35238bceSAndroid Build Coastguard Worker                              GL_DYNAMIC_DRAW, 1728, << IVec2(729, 999) << IVec2(0, 729));
716*35238bceSAndroid Build Coastguard Worker         PARTIAL_SPECIFY_CASE(whole_3, "Whole buffer specification with three calls", GL_ARRAY_BUFFER, GL_STREAM_DRAW,
717*35238bceSAndroid Build Coastguard Worker                              1944, << IVec2(0, 421) << IVec2(1421, 523) << IVec2(421, 1000));
718*35238bceSAndroid Build Coastguard Worker         PARTIAL_SPECIFY_CASE(whole_4, "Whole buffer specification with three calls", GL_ELEMENT_ARRAY_BUFFER,
719*35238bceSAndroid Build Coastguard Worker                              GL_STREAM_DRAW, 1200, << IVec2(0, 500) << IVec2(429, 200) << IVec2(513, 687));
720*35238bceSAndroid Build Coastguard Worker 
721*35238bceSAndroid Build Coastguard Worker         PARTIAL_SPECIFY_CASE(low_1, "Low part of buffer specified with single call", GL_ELEMENT_ARRAY_BUFFER,
722*35238bceSAndroid Build Coastguard Worker                              GL_STATIC_DRAW, 1000, << IVec2(0, 513));
723*35238bceSAndroid Build Coastguard Worker         PARTIAL_SPECIFY_CASE(low_2, "Low part of buffer specified with two calls", GL_ARRAY_BUFFER, GL_STATIC_DRAW, 996,
724*35238bceSAndroid Build Coastguard Worker                              << IVec2(0, 98) << IVec2(98, 511));
725*35238bceSAndroid Build Coastguard Worker         PARTIAL_SPECIFY_CASE(low_3, "Low part of buffer specified with two calls", GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW,
726*35238bceSAndroid Build Coastguard Worker                              1200, << IVec2(0, 591) << IVec2(371, 400));
727*35238bceSAndroid Build Coastguard Worker 
728*35238bceSAndroid Build Coastguard Worker         PARTIAL_SPECIFY_CASE(high_1, "High part of buffer specified with single call", GL_ELEMENT_ARRAY_BUFFER,
729*35238bceSAndroid Build Coastguard Worker                              GL_STATIC_DRAW, 1000, << IVec2(500, 500));
730*35238bceSAndroid Build Coastguard Worker         PARTIAL_SPECIFY_CASE(high_2, "High part of buffer specified with two calls", GL_ARRAY_BUFFER, GL_STREAM_DRAW,
731*35238bceSAndroid Build Coastguard Worker                              1200, << IVec2(600, 123) << IVec2(723, 477));
732*35238bceSAndroid Build Coastguard Worker         PARTIAL_SPECIFY_CASE(high_3, "High part of buffer specified with two calls", GL_ARRAY_BUFFER, GL_STREAM_DRAW,
733*35238bceSAndroid Build Coastguard Worker                              1200, << IVec2(600, 200) << IVec2(601, 599));
734*35238bceSAndroid Build Coastguard Worker 
735*35238bceSAndroid Build Coastguard Worker         PARTIAL_SPECIFY_CASE(middle_1, "Middle part of buffer specified with single call", GL_ELEMENT_ARRAY_BUFFER,
736*35238bceSAndroid Build Coastguard Worker                              GL_STREAM_DRAW, 2500, << IVec2(1000, 799));
737*35238bceSAndroid Build Coastguard Worker         PARTIAL_SPECIFY_CASE(middle_2, "Middle part of buffer specified with two calls", GL_ELEMENT_ARRAY_BUFFER,
738*35238bceSAndroid Build Coastguard Worker                              GL_STATIC_DRAW, 2500, << IVec2(780, 220) << IVec2(1000, 500));
739*35238bceSAndroid Build Coastguard Worker         PARTIAL_SPECIFY_CASE(middle_3, "Middle part of buffer specified with two calls", GL_ARRAY_BUFFER,
740*35238bceSAndroid Build Coastguard Worker                              GL_DYNAMIC_DRAW, 2500, << IVec2(780, 321) << IVec2(1000, 501));
741*35238bceSAndroid Build Coastguard Worker 
742*35238bceSAndroid Build Coastguard Worker #undef PARTIAL_SPECIFY_CASE
743*35238bceSAndroid Build Coastguard Worker     }
744*35238bceSAndroid Build Coastguard Worker 
745*35238bceSAndroid Build Coastguard Worker     // .random
746*35238bceSAndroid Build Coastguard Worker     {
747*35238bceSAndroid Build Coastguard Worker         tcu::TestCaseGroup *const randomGroup =
748*35238bceSAndroid Build Coastguard Worker             new tcu::TestCaseGroup(m_testCtx, "random", "Randomized buffer data cases");
749*35238bceSAndroid Build Coastguard Worker         addChild(randomGroup);
750*35238bceSAndroid Build Coastguard Worker 
751*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < 10; i++)
752*35238bceSAndroid Build Coastguard Worker             randomGroup->addChild(new RandomBufferWriteCase(m_context, de::toString(i).c_str(), "", deInt32Hash(i)));
753*35238bceSAndroid Build Coastguard Worker     }
754*35238bceSAndroid Build Coastguard Worker }
755*35238bceSAndroid Build Coastguard Worker 
756*35238bceSAndroid Build Coastguard Worker } // namespace Functional
757*35238bceSAndroid Build Coastguard Worker } // namespace gles2
758*35238bceSAndroid Build Coastguard Worker } // namespace deqp
759