xref: /aosp_15_r20/external/deqp/modules/gles2/functional/es2fBufferTestUtil.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 test utilities.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es2fBufferTestUtil.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "tcuRandomValueIterator.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuVector.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuFormatUtil.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "deMemory.h"
37*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
38*35238bceSAndroid Build Coastguard Worker 
39*35238bceSAndroid Build Coastguard Worker #include <algorithm>
40*35238bceSAndroid Build Coastguard Worker 
41*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
43*35238bceSAndroid Build Coastguard Worker 
44*35238bceSAndroid Build Coastguard Worker namespace deqp
45*35238bceSAndroid Build Coastguard Worker {
46*35238bceSAndroid Build Coastguard Worker namespace gles2
47*35238bceSAndroid Build Coastguard Worker {
48*35238bceSAndroid Build Coastguard Worker namespace Functional
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker namespace BufferTestUtil
51*35238bceSAndroid Build Coastguard Worker {
52*35238bceSAndroid Build Coastguard Worker 
53*35238bceSAndroid Build Coastguard Worker enum
54*35238bceSAndroid Build Coastguard Worker {
55*35238bceSAndroid Build Coastguard Worker     VERIFY_QUAD_SIZE                 = 8,   //!< Quad size in VertexArrayVerifier
56*35238bceSAndroid Build Coastguard Worker     MAX_LINES_PER_INDEX_ARRAY_DRAW   = 128, //!< Maximum number of lines per one draw in IndexArrayVerifier
57*35238bceSAndroid Build Coastguard Worker     INDEX_ARRAY_DRAW_VIEWPORT_WIDTH  = 128,
58*35238bceSAndroid Build Coastguard Worker     INDEX_ARRAY_DRAW_VIEWPORT_HEIGHT = 128
59*35238bceSAndroid Build Coastguard Worker };
60*35238bceSAndroid Build Coastguard Worker 
61*35238bceSAndroid Build Coastguard Worker static const bool LOG_VERIFIER_CALLS = false; //! \note Especially array verifier generates a lot of calls.
62*35238bceSAndroid Build Coastguard Worker 
63*35238bceSAndroid Build Coastguard Worker using std::set;
64*35238bceSAndroid Build Coastguard Worker using std::string;
65*35238bceSAndroid Build Coastguard Worker using std::vector;
66*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
67*35238bceSAndroid Build Coastguard Worker 
68*35238bceSAndroid Build Coastguard Worker // Helper functions.
69*35238bceSAndroid Build Coastguard Worker 
fillWithRandomBytes(uint8_t * ptr,int numBytes,uint32_t seed)70*35238bceSAndroid Build Coastguard Worker void fillWithRandomBytes(uint8_t *ptr, int numBytes, uint32_t seed)
71*35238bceSAndroid Build Coastguard Worker {
72*35238bceSAndroid Build Coastguard Worker     std::copy(tcu::RandomValueIterator<uint8_t>::begin(seed, numBytes), tcu::RandomValueIterator<uint8_t>::end(), ptr);
73*35238bceSAndroid Build Coastguard Worker }
74*35238bceSAndroid Build Coastguard Worker 
compareByteArrays(tcu::TestLog & log,const uint8_t * resPtr,const uint8_t * refPtr,int numBytes)75*35238bceSAndroid Build Coastguard Worker bool compareByteArrays(tcu::TestLog &log, const uint8_t *resPtr, const uint8_t *refPtr, int numBytes)
76*35238bceSAndroid Build Coastguard Worker {
77*35238bceSAndroid Build Coastguard Worker     bool isOk              = true;
78*35238bceSAndroid Build Coastguard Worker     const int maxSpanLen   = 8;
79*35238bceSAndroid Build Coastguard Worker     const int maxDiffSpans = 4;
80*35238bceSAndroid Build Coastguard Worker     int numDiffSpans       = 0;
81*35238bceSAndroid Build Coastguard Worker     int diffSpanStart      = -1;
82*35238bceSAndroid Build Coastguard Worker     int ndx                = 0;
83*35238bceSAndroid Build Coastguard Worker 
84*35238bceSAndroid Build Coastguard Worker     log << TestLog::Section("Verify", "Verification result");
85*35238bceSAndroid Build Coastguard Worker 
86*35238bceSAndroid Build Coastguard Worker     for (; ndx < numBytes; ndx++)
87*35238bceSAndroid Build Coastguard Worker     {
88*35238bceSAndroid Build Coastguard Worker         if (resPtr[ndx] != refPtr[ndx])
89*35238bceSAndroid Build Coastguard Worker         {
90*35238bceSAndroid Build Coastguard Worker             if (diffSpanStart < 0)
91*35238bceSAndroid Build Coastguard Worker                 diffSpanStart = ndx;
92*35238bceSAndroid Build Coastguard Worker 
93*35238bceSAndroid Build Coastguard Worker             isOk = false;
94*35238bceSAndroid Build Coastguard Worker         }
95*35238bceSAndroid Build Coastguard Worker         else if (diffSpanStart >= 0)
96*35238bceSAndroid Build Coastguard Worker         {
97*35238bceSAndroid Build Coastguard Worker             if (numDiffSpans < maxDiffSpans)
98*35238bceSAndroid Build Coastguard Worker             {
99*35238bceSAndroid Build Coastguard Worker                 int len      = ndx - diffSpanStart;
100*35238bceSAndroid Build Coastguard Worker                 int printLen = de::min(len, maxSpanLen);
101*35238bceSAndroid Build Coastguard Worker 
102*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message << len << " byte difference at offset " << diffSpanStart << "\n"
103*35238bceSAndroid Build Coastguard Worker                     << "  expected "
104*35238bceSAndroid Build Coastguard Worker                     << tcu::formatArray(tcu::Format::HexIterator<uint8_t>(refPtr + diffSpanStart),
105*35238bceSAndroid Build Coastguard Worker                                         tcu::Format::HexIterator<uint8_t>(refPtr + diffSpanStart + printLen))
106*35238bceSAndroid Build Coastguard Worker                     << "\n"
107*35238bceSAndroid Build Coastguard Worker                     << "  got "
108*35238bceSAndroid Build Coastguard Worker                     << tcu::formatArray(tcu::Format::HexIterator<uint8_t>(resPtr + diffSpanStart),
109*35238bceSAndroid Build Coastguard Worker                                         tcu::Format::HexIterator<uint8_t>(resPtr + diffSpanStart + printLen))
110*35238bceSAndroid Build Coastguard Worker                     << TestLog::EndMessage;
111*35238bceSAndroid Build Coastguard Worker             }
112*35238bceSAndroid Build Coastguard Worker             else
113*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message << "(output too long, truncated)" << TestLog::EndMessage;
114*35238bceSAndroid Build Coastguard Worker 
115*35238bceSAndroid Build Coastguard Worker             numDiffSpans += 1;
116*35238bceSAndroid Build Coastguard Worker             diffSpanStart = -1;
117*35238bceSAndroid Build Coastguard Worker         }
118*35238bceSAndroid Build Coastguard Worker     }
119*35238bceSAndroid Build Coastguard Worker 
120*35238bceSAndroid Build Coastguard Worker     if (diffSpanStart >= 0)
121*35238bceSAndroid Build Coastguard Worker     {
122*35238bceSAndroid Build Coastguard Worker         if (numDiffSpans < maxDiffSpans)
123*35238bceSAndroid Build Coastguard Worker         {
124*35238bceSAndroid Build Coastguard Worker             int len      = ndx - diffSpanStart;
125*35238bceSAndroid Build Coastguard Worker             int printLen = de::min(len, maxSpanLen);
126*35238bceSAndroid Build Coastguard Worker 
127*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << len << " byte difference at offset " << diffSpanStart << "\n"
128*35238bceSAndroid Build Coastguard Worker                 << "  expected "
129*35238bceSAndroid Build Coastguard Worker                 << tcu::formatArray(tcu::Format::HexIterator<uint8_t>(refPtr + diffSpanStart),
130*35238bceSAndroid Build Coastguard Worker                                     tcu::Format::HexIterator<uint8_t>(refPtr + diffSpanStart + printLen))
131*35238bceSAndroid Build Coastguard Worker                 << "\n"
132*35238bceSAndroid Build Coastguard Worker                 << "  got "
133*35238bceSAndroid Build Coastguard Worker                 << tcu::formatArray(tcu::Format::HexIterator<uint8_t>(resPtr + diffSpanStart),
134*35238bceSAndroid Build Coastguard Worker                                     tcu::Format::HexIterator<uint8_t>(resPtr + diffSpanStart + printLen))
135*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
136*35238bceSAndroid Build Coastguard Worker         }
137*35238bceSAndroid Build Coastguard Worker         else
138*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "(output too long, truncated)" << TestLog::EndMessage;
139*35238bceSAndroid Build Coastguard Worker     }
140*35238bceSAndroid Build Coastguard Worker 
141*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << (isOk ? "Verification passed." : "Verification FAILED!") << TestLog::EndMessage;
142*35238bceSAndroid Build Coastguard Worker     log << TestLog::EndSection;
143*35238bceSAndroid Build Coastguard Worker 
144*35238bceSAndroid Build Coastguard Worker     return isOk;
145*35238bceSAndroid Build Coastguard Worker }
146*35238bceSAndroid Build Coastguard Worker 
getBufferTargetName(uint32_t target)147*35238bceSAndroid Build Coastguard Worker const char *getBufferTargetName(uint32_t target)
148*35238bceSAndroid Build Coastguard Worker {
149*35238bceSAndroid Build Coastguard Worker     switch (target)
150*35238bceSAndroid Build Coastguard Worker     {
151*35238bceSAndroid Build Coastguard Worker     case GL_ARRAY_BUFFER:
152*35238bceSAndroid Build Coastguard Worker         return "array";
153*35238bceSAndroid Build Coastguard Worker     case GL_ELEMENT_ARRAY_BUFFER:
154*35238bceSAndroid Build Coastguard Worker         return "element_array";
155*35238bceSAndroid Build Coastguard Worker     default:
156*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
157*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
158*35238bceSAndroid Build Coastguard Worker     }
159*35238bceSAndroid Build Coastguard Worker }
160*35238bceSAndroid Build Coastguard Worker 
getUsageHintName(uint32_t hint)161*35238bceSAndroid Build Coastguard Worker const char *getUsageHintName(uint32_t hint)
162*35238bceSAndroid Build Coastguard Worker {
163*35238bceSAndroid Build Coastguard Worker     switch (hint)
164*35238bceSAndroid Build Coastguard Worker     {
165*35238bceSAndroid Build Coastguard Worker     case GL_STREAM_DRAW:
166*35238bceSAndroid Build Coastguard Worker         return "stream_draw";
167*35238bceSAndroid Build Coastguard Worker     case GL_STATIC_DRAW:
168*35238bceSAndroid Build Coastguard Worker         return "static_draw";
169*35238bceSAndroid Build Coastguard Worker     case GL_DYNAMIC_DRAW:
170*35238bceSAndroid Build Coastguard Worker         return "dynamic_draw";
171*35238bceSAndroid Build Coastguard Worker     default:
172*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
173*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
174*35238bceSAndroid Build Coastguard Worker     }
175*35238bceSAndroid Build Coastguard Worker }
176*35238bceSAndroid Build Coastguard Worker 
177*35238bceSAndroid Build Coastguard Worker // BufferCase
178*35238bceSAndroid Build Coastguard Worker 
BufferCase(Context & context,const char * name,const char * description)179*35238bceSAndroid Build Coastguard Worker BufferCase::BufferCase(Context &context, const char *name, const char *description)
180*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
181*35238bceSAndroid Build Coastguard Worker     , CallLogWrapper(context.getRenderContext().getFunctions(), m_context.getTestContext().getLog())
182*35238bceSAndroid Build Coastguard Worker {
183*35238bceSAndroid Build Coastguard Worker }
184*35238bceSAndroid Build Coastguard Worker 
~BufferCase(void)185*35238bceSAndroid Build Coastguard Worker BufferCase::~BufferCase(void)
186*35238bceSAndroid Build Coastguard Worker {
187*35238bceSAndroid Build Coastguard Worker     enableLogging(false);
188*35238bceSAndroid Build Coastguard Worker     BufferCase::deinit();
189*35238bceSAndroid Build Coastguard Worker }
190*35238bceSAndroid Build Coastguard Worker 
init(void)191*35238bceSAndroid Build Coastguard Worker void BufferCase::init(void)
192*35238bceSAndroid Build Coastguard Worker {
193*35238bceSAndroid Build Coastguard Worker     enableLogging(true);
194*35238bceSAndroid Build Coastguard Worker }
195*35238bceSAndroid Build Coastguard Worker 
deinit(void)196*35238bceSAndroid Build Coastguard Worker void BufferCase::deinit(void)
197*35238bceSAndroid Build Coastguard Worker {
198*35238bceSAndroid Build Coastguard Worker     for (set<uint32_t>::const_iterator bufIter = m_allocatedBuffers.begin(); bufIter != m_allocatedBuffers.end();
199*35238bceSAndroid Build Coastguard Worker          bufIter++)
200*35238bceSAndroid Build Coastguard Worker         glDeleteBuffers(1, &(*bufIter));
201*35238bceSAndroid Build Coastguard Worker }
202*35238bceSAndroid Build Coastguard Worker 
genBuffer(void)203*35238bceSAndroid Build Coastguard Worker uint32_t BufferCase::genBuffer(void)
204*35238bceSAndroid Build Coastguard Worker {
205*35238bceSAndroid Build Coastguard Worker     uint32_t buf = 0;
206*35238bceSAndroid Build Coastguard Worker     glGenBuffers(1, &buf);
207*35238bceSAndroid Build Coastguard Worker     if (buf != 0)
208*35238bceSAndroid Build Coastguard Worker     {
209*35238bceSAndroid Build Coastguard Worker         try
210*35238bceSAndroid Build Coastguard Worker         {
211*35238bceSAndroid Build Coastguard Worker             m_allocatedBuffers.insert(buf);
212*35238bceSAndroid Build Coastguard Worker         }
213*35238bceSAndroid Build Coastguard Worker         catch (const std::exception &)
214*35238bceSAndroid Build Coastguard Worker         {
215*35238bceSAndroid Build Coastguard Worker             glDeleteBuffers(1, &buf);
216*35238bceSAndroid Build Coastguard Worker             throw;
217*35238bceSAndroid Build Coastguard Worker         }
218*35238bceSAndroid Build Coastguard Worker     }
219*35238bceSAndroid Build Coastguard Worker     return buf;
220*35238bceSAndroid Build Coastguard Worker }
221*35238bceSAndroid Build Coastguard Worker 
deleteBuffer(uint32_t buffer)222*35238bceSAndroid Build Coastguard Worker void BufferCase::deleteBuffer(uint32_t buffer)
223*35238bceSAndroid Build Coastguard Worker {
224*35238bceSAndroid Build Coastguard Worker     glDeleteBuffers(1, &buffer);
225*35238bceSAndroid Build Coastguard Worker     m_allocatedBuffers.erase(buffer);
226*35238bceSAndroid Build Coastguard Worker }
227*35238bceSAndroid Build Coastguard Worker 
checkError(void)228*35238bceSAndroid Build Coastguard Worker void BufferCase::checkError(void)
229*35238bceSAndroid Build Coastguard Worker {
230*35238bceSAndroid Build Coastguard Worker     glw::GLenum err = glGetError();
231*35238bceSAndroid Build Coastguard Worker     if (err != GL_NO_ERROR)
232*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError(string("Got ") + glu::getErrorStr(err).toString());
233*35238bceSAndroid Build Coastguard Worker }
234*35238bceSAndroid Build Coastguard Worker 
235*35238bceSAndroid Build Coastguard Worker // ReferenceBuffer
236*35238bceSAndroid Build Coastguard Worker 
setSize(int numBytes)237*35238bceSAndroid Build Coastguard Worker void ReferenceBuffer::setSize(int numBytes)
238*35238bceSAndroid Build Coastguard Worker {
239*35238bceSAndroid Build Coastguard Worker     m_data.resize(numBytes);
240*35238bceSAndroid Build Coastguard Worker }
241*35238bceSAndroid Build Coastguard Worker 
setData(int numBytes,const uint8_t * bytes)242*35238bceSAndroid Build Coastguard Worker void ReferenceBuffer::setData(int numBytes, const uint8_t *bytes)
243*35238bceSAndroid Build Coastguard Worker {
244*35238bceSAndroid Build Coastguard Worker     m_data.resize(numBytes);
245*35238bceSAndroid Build Coastguard Worker     std::copy(bytes, bytes + numBytes, m_data.begin());
246*35238bceSAndroid Build Coastguard Worker }
247*35238bceSAndroid Build Coastguard Worker 
setSubData(int offset,int numBytes,const uint8_t * bytes)248*35238bceSAndroid Build Coastguard Worker void ReferenceBuffer::setSubData(int offset, int numBytes, const uint8_t *bytes)
249*35238bceSAndroid Build Coastguard Worker {
250*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inBounds(offset, 0, (int)m_data.size()) &&
251*35238bceSAndroid Build Coastguard Worker               de::inRange(offset + numBytes, offset, (int)m_data.size()));
252*35238bceSAndroid Build Coastguard Worker     std::copy(bytes, bytes + numBytes, m_data.begin() + offset);
253*35238bceSAndroid Build Coastguard Worker }
254*35238bceSAndroid Build Coastguard Worker 
255*35238bceSAndroid Build Coastguard Worker // BufferVerifierBase
256*35238bceSAndroid Build Coastguard Worker 
BufferVerifierBase(Context & context)257*35238bceSAndroid Build Coastguard Worker BufferVerifierBase::BufferVerifierBase(Context &context)
258*35238bceSAndroid Build Coastguard Worker     : CallLogWrapper(context.getRenderContext().getFunctions(), context.getTestContext().getLog())
259*35238bceSAndroid Build Coastguard Worker     , m_context(context)
260*35238bceSAndroid Build Coastguard Worker {
261*35238bceSAndroid Build Coastguard Worker     enableLogging(LOG_VERIFIER_CALLS);
262*35238bceSAndroid Build Coastguard Worker }
263*35238bceSAndroid Build Coastguard Worker 
264*35238bceSAndroid Build Coastguard Worker // BufferVerifier
265*35238bceSAndroid Build Coastguard Worker 
BufferVerifier(Context & context,VerifyType verifyType)266*35238bceSAndroid Build Coastguard Worker BufferVerifier::BufferVerifier(Context &context, VerifyType verifyType) : m_verifier(DE_NULL)
267*35238bceSAndroid Build Coastguard Worker {
268*35238bceSAndroid Build Coastguard Worker     switch (verifyType)
269*35238bceSAndroid Build Coastguard Worker     {
270*35238bceSAndroid Build Coastguard Worker     case VERIFY_AS_VERTEX_ARRAY:
271*35238bceSAndroid Build Coastguard Worker         m_verifier = new VertexArrayVerifier(context);
272*35238bceSAndroid Build Coastguard Worker         break;
273*35238bceSAndroid Build Coastguard Worker     case VERIFY_AS_INDEX_ARRAY:
274*35238bceSAndroid Build Coastguard Worker         m_verifier = new IndexArrayVerifier(context);
275*35238bceSAndroid Build Coastguard Worker         break;
276*35238bceSAndroid Build Coastguard Worker     default:
277*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Unsupported verifier");
278*35238bceSAndroid Build Coastguard Worker     }
279*35238bceSAndroid Build Coastguard Worker }
280*35238bceSAndroid Build Coastguard Worker 
~BufferVerifier(void)281*35238bceSAndroid Build Coastguard Worker BufferVerifier::~BufferVerifier(void)
282*35238bceSAndroid Build Coastguard Worker {
283*35238bceSAndroid Build Coastguard Worker     delete m_verifier;
284*35238bceSAndroid Build Coastguard Worker }
285*35238bceSAndroid Build Coastguard Worker 
verify(uint32_t buffer,const uint8_t * reference,int offset,int numBytes)286*35238bceSAndroid Build Coastguard Worker bool BufferVerifier::verify(uint32_t buffer, const uint8_t *reference, int offset, int numBytes)
287*35238bceSAndroid Build Coastguard Worker {
288*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numBytes >= getMinSize());
289*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(offset % getAlignment() == 0);
290*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((offset + numBytes) % getAlignment() == 0);
291*35238bceSAndroid Build Coastguard Worker     return m_verifier->verify(buffer, reference, offset, numBytes);
292*35238bceSAndroid Build Coastguard Worker }
293*35238bceSAndroid Build Coastguard Worker 
294*35238bceSAndroid Build Coastguard Worker // VertexArrayVerifier
295*35238bceSAndroid Build Coastguard Worker 
VertexArrayVerifier(Context & context)296*35238bceSAndroid Build Coastguard Worker VertexArrayVerifier::VertexArrayVerifier(Context &context)
297*35238bceSAndroid Build Coastguard Worker     : BufferVerifierBase(context)
298*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
299*35238bceSAndroid Build Coastguard Worker     , m_posLoc(0)
300*35238bceSAndroid Build Coastguard Worker     , m_byteVecLoc(0)
301*35238bceSAndroid Build Coastguard Worker {
302*35238bceSAndroid Build Coastguard Worker     m_program = new glu::ShaderProgram(m_context.getRenderContext(),
303*35238bceSAndroid Build Coastguard Worker                                        glu::makeVtxFragSources("attribute highp vec2 a_position;\n"
304*35238bceSAndroid Build Coastguard Worker                                                                "attribute mediump vec3 a_byteVec;\n"
305*35238bceSAndroid Build Coastguard Worker                                                                "varying mediump vec3 v_byteVec;\n"
306*35238bceSAndroid Build Coastguard Worker                                                                "void main (void)\n"
307*35238bceSAndroid Build Coastguard Worker                                                                "{\n"
308*35238bceSAndroid Build Coastguard Worker                                                                "    gl_Position = vec4(a_position, 0.0, 1.0);\n"
309*35238bceSAndroid Build Coastguard Worker                                                                "    v_byteVec = a_byteVec;\n"
310*35238bceSAndroid Build Coastguard Worker                                                                "}\n",
311*35238bceSAndroid Build Coastguard Worker 
312*35238bceSAndroid Build Coastguard Worker                                                                "varying mediump vec3 v_byteVec;\n"
313*35238bceSAndroid Build Coastguard Worker                                                                "void main (void)\n"
314*35238bceSAndroid Build Coastguard Worker                                                                "{\n"
315*35238bceSAndroid Build Coastguard Worker                                                                "    gl_FragColor = vec4(v_byteVec, 1.0);\n"
316*35238bceSAndroid Build Coastguard Worker                                                                "}\n"));
317*35238bceSAndroid Build Coastguard Worker 
318*35238bceSAndroid Build Coastguard Worker     if (!m_program->isOk())
319*35238bceSAndroid Build Coastguard Worker     {
320*35238bceSAndroid Build Coastguard Worker         m_context.getTestContext().getLog() << *m_program;
321*35238bceSAndroid Build Coastguard Worker         delete m_program;
322*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Compile failed");
323*35238bceSAndroid Build Coastguard Worker     }
324*35238bceSAndroid Build Coastguard Worker 
325*35238bceSAndroid Build Coastguard Worker     const glw::Functions &funcs = context.getRenderContext().getFunctions();
326*35238bceSAndroid Build Coastguard Worker     m_posLoc                    = funcs.getAttribLocation(m_program->getProgram(), "a_position");
327*35238bceSAndroid Build Coastguard Worker     m_byteVecLoc                = funcs.getAttribLocation(m_program->getProgram(), "a_byteVec");
328*35238bceSAndroid Build Coastguard Worker }
329*35238bceSAndroid Build Coastguard Worker 
~VertexArrayVerifier(void)330*35238bceSAndroid Build Coastguard Worker VertexArrayVerifier::~VertexArrayVerifier(void)
331*35238bceSAndroid Build Coastguard Worker {
332*35238bceSAndroid Build Coastguard Worker     delete m_program;
333*35238bceSAndroid Build Coastguard Worker }
334*35238bceSAndroid Build Coastguard Worker 
computePositions(vector<tcu::Vec2> & positions,int gridSizeX,int gridSizeY)335*35238bceSAndroid Build Coastguard Worker static void computePositions(vector<tcu::Vec2> &positions, int gridSizeX, int gridSizeY)
336*35238bceSAndroid Build Coastguard Worker {
337*35238bceSAndroid Build Coastguard Worker     positions.resize(gridSizeX * gridSizeY * 4);
338*35238bceSAndroid Build Coastguard Worker 
339*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < gridSizeY; y++)
340*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < gridSizeX; x++)
341*35238bceSAndroid Build Coastguard Worker         {
342*35238bceSAndroid Build Coastguard Worker             float sx0   = (float)(x + 0) / (float)gridSizeX;
343*35238bceSAndroid Build Coastguard Worker             float sy0   = (float)(y + 0) / (float)gridSizeY;
344*35238bceSAndroid Build Coastguard Worker             float sx1   = (float)(x + 1) / (float)gridSizeX;
345*35238bceSAndroid Build Coastguard Worker             float sy1   = (float)(y + 1) / (float)gridSizeY;
346*35238bceSAndroid Build Coastguard Worker             float fx0   = 2.0f * sx0 - 1.0f;
347*35238bceSAndroid Build Coastguard Worker             float fy0   = 2.0f * sy0 - 1.0f;
348*35238bceSAndroid Build Coastguard Worker             float fx1   = 2.0f * sx1 - 1.0f;
349*35238bceSAndroid Build Coastguard Worker             float fy1   = 2.0f * sy1 - 1.0f;
350*35238bceSAndroid Build Coastguard Worker             int baseNdx = (y * gridSizeX + x) * 4;
351*35238bceSAndroid Build Coastguard Worker 
352*35238bceSAndroid Build Coastguard Worker             positions[baseNdx + 0] = tcu::Vec2(fx0, fy0);
353*35238bceSAndroid Build Coastguard Worker             positions[baseNdx + 1] = tcu::Vec2(fx0, fy1);
354*35238bceSAndroid Build Coastguard Worker             positions[baseNdx + 2] = tcu::Vec2(fx1, fy0);
355*35238bceSAndroid Build Coastguard Worker             positions[baseNdx + 3] = tcu::Vec2(fx1, fy1);
356*35238bceSAndroid Build Coastguard Worker         }
357*35238bceSAndroid Build Coastguard Worker }
358*35238bceSAndroid Build Coastguard Worker 
computeIndices(vector<uint16_t> & indices,int gridSizeX,int gridSizeY)359*35238bceSAndroid Build Coastguard Worker static void computeIndices(vector<uint16_t> &indices, int gridSizeX, int gridSizeY)
360*35238bceSAndroid Build Coastguard Worker {
361*35238bceSAndroid Build Coastguard Worker     indices.resize(3 * 2 * gridSizeX * gridSizeY);
362*35238bceSAndroid Build Coastguard Worker 
363*35238bceSAndroid Build Coastguard Worker     for (int quadNdx = 0; quadNdx < gridSizeX * gridSizeY; quadNdx++)
364*35238bceSAndroid Build Coastguard Worker     {
365*35238bceSAndroid Build Coastguard Worker         int v00 = quadNdx * 4 + 0;
366*35238bceSAndroid Build Coastguard Worker         int v01 = quadNdx * 4 + 1;
367*35238bceSAndroid Build Coastguard Worker         int v10 = quadNdx * 4 + 2;
368*35238bceSAndroid Build Coastguard Worker         int v11 = quadNdx * 4 + 3;
369*35238bceSAndroid Build Coastguard Worker 
370*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(v11 < (1 << 16));
371*35238bceSAndroid Build Coastguard Worker 
372*35238bceSAndroid Build Coastguard Worker         indices[quadNdx * 6 + 0] = (uint16_t)v10;
373*35238bceSAndroid Build Coastguard Worker         indices[quadNdx * 6 + 1] = (uint16_t)v00;
374*35238bceSAndroid Build Coastguard Worker         indices[quadNdx * 6 + 2] = (uint16_t)v01;
375*35238bceSAndroid Build Coastguard Worker 
376*35238bceSAndroid Build Coastguard Worker         indices[quadNdx * 6 + 3] = (uint16_t)v10;
377*35238bceSAndroid Build Coastguard Worker         indices[quadNdx * 6 + 4] = (uint16_t)v01;
378*35238bceSAndroid Build Coastguard Worker         indices[quadNdx * 6 + 5] = (uint16_t)v11;
379*35238bceSAndroid Build Coastguard Worker     }
380*35238bceSAndroid Build Coastguard Worker }
381*35238bceSAndroid Build Coastguard Worker 
fetchVtxColor(const uint8_t * ptr,int vtxNdx)382*35238bceSAndroid Build Coastguard Worker static inline tcu::Vec4 fetchVtxColor(const uint8_t *ptr, int vtxNdx)
383*35238bceSAndroid Build Coastguard Worker {
384*35238bceSAndroid Build Coastguard Worker     return tcu::RGBA(*(ptr + vtxNdx * 3 + 0), *(ptr + vtxNdx * 3 + 1), *(ptr + vtxNdx * 3 + 2), 255).toVec();
385*35238bceSAndroid Build Coastguard Worker }
386*35238bceSAndroid Build Coastguard Worker 
renderQuadGridReference(tcu::Surface & dst,int numQuads,int rowLength,const uint8_t * inPtr)387*35238bceSAndroid Build Coastguard Worker static void renderQuadGridReference(tcu::Surface &dst, int numQuads, int rowLength, const uint8_t *inPtr)
388*35238bceSAndroid Build Coastguard Worker {
389*35238bceSAndroid Build Coastguard Worker     using tcu::Vec4;
390*35238bceSAndroid Build Coastguard Worker 
391*35238bceSAndroid Build Coastguard Worker     dst.setSize(rowLength * VERIFY_QUAD_SIZE,
392*35238bceSAndroid Build Coastguard Worker                 (numQuads / rowLength + (numQuads % rowLength != 0 ? 1 : 0)) * VERIFY_QUAD_SIZE);
393*35238bceSAndroid Build Coastguard Worker 
394*35238bceSAndroid Build Coastguard Worker     tcu::PixelBufferAccess dstAccess = dst.getAccess();
395*35238bceSAndroid Build Coastguard Worker     tcu::clear(dstAccess, tcu::IVec4(0, 0, 0, 0xff));
396*35238bceSAndroid Build Coastguard Worker 
397*35238bceSAndroid Build Coastguard Worker     for (int quadNdx = 0; quadNdx < numQuads; quadNdx++)
398*35238bceSAndroid Build Coastguard Worker     {
399*35238bceSAndroid Build Coastguard Worker         int x0   = (quadNdx % rowLength) * VERIFY_QUAD_SIZE;
400*35238bceSAndroid Build Coastguard Worker         int y0   = (quadNdx / rowLength) * VERIFY_QUAD_SIZE;
401*35238bceSAndroid Build Coastguard Worker         Vec4 v00 = fetchVtxColor(inPtr, quadNdx * 4 + 0);
402*35238bceSAndroid Build Coastguard Worker         Vec4 v10 = fetchVtxColor(inPtr, quadNdx * 4 + 1);
403*35238bceSAndroid Build Coastguard Worker         Vec4 v01 = fetchVtxColor(inPtr, quadNdx * 4 + 2);
404*35238bceSAndroid Build Coastguard Worker         Vec4 v11 = fetchVtxColor(inPtr, quadNdx * 4 + 3);
405*35238bceSAndroid Build Coastguard Worker 
406*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < VERIFY_QUAD_SIZE; y++)
407*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < VERIFY_QUAD_SIZE; x++)
408*35238bceSAndroid Build Coastguard Worker             {
409*35238bceSAndroid Build Coastguard Worker                 float fx = ((float)x + 0.5f) / (float)VERIFY_QUAD_SIZE;
410*35238bceSAndroid Build Coastguard Worker                 float fy = ((float)y + 0.5f) / (float)VERIFY_QUAD_SIZE;
411*35238bceSAndroid Build Coastguard Worker 
412*35238bceSAndroid Build Coastguard Worker                 bool tri       = fx + fy <= 1.0f;
413*35238bceSAndroid Build Coastguard Worker                 float tx       = tri ? fx : (1.0f - fx);
414*35238bceSAndroid Build Coastguard Worker                 float ty       = tri ? fy : (1.0f - fy);
415*35238bceSAndroid Build Coastguard Worker                 const Vec4 &t0 = tri ? v00 : v11;
416*35238bceSAndroid Build Coastguard Worker                 const Vec4 &t1 = tri ? v01 : v10;
417*35238bceSAndroid Build Coastguard Worker                 const Vec4 &t2 = tri ? v10 : v01;
418*35238bceSAndroid Build Coastguard Worker                 Vec4 color     = t0 + (t1 - t0) * tx + (t2 - t0) * ty;
419*35238bceSAndroid Build Coastguard Worker 
420*35238bceSAndroid Build Coastguard Worker                 dstAccess.setPixel(color, x0 + x, y0 + y);
421*35238bceSAndroid Build Coastguard Worker             }
422*35238bceSAndroid Build Coastguard Worker     }
423*35238bceSAndroid Build Coastguard Worker }
424*35238bceSAndroid Build Coastguard Worker 
verify(uint32_t buffer,const uint8_t * refPtr,int offset,int numBytes)425*35238bceSAndroid Build Coastguard Worker bool VertexArrayVerifier::verify(uint32_t buffer, const uint8_t *refPtr, int offset, int numBytes)
426*35238bceSAndroid Build Coastguard Worker {
427*35238bceSAndroid Build Coastguard Worker     const tcu::RenderTarget &renderTarget = m_context.getRenderContext().getRenderTarget();
428*35238bceSAndroid Build Coastguard Worker     const int numBytesInVtx               = 3;
429*35238bceSAndroid Build Coastguard Worker     const int numBytesInQuad              = numBytesInVtx * 4;
430*35238bceSAndroid Build Coastguard Worker     int maxQuadsX                         = de::min(128, renderTarget.getWidth() / VERIFY_QUAD_SIZE);
431*35238bceSAndroid Build Coastguard Worker     int maxQuadsY                         = de::min(128, renderTarget.getHeight() / VERIFY_QUAD_SIZE);
432*35238bceSAndroid Build Coastguard Worker     int maxQuadsPerBatch                  = maxQuadsX * maxQuadsY;
433*35238bceSAndroid Build Coastguard Worker     int numVerified                       = 0;
434*35238bceSAndroid Build Coastguard Worker     uint32_t program                      = m_program->getProgram();
435*35238bceSAndroid Build Coastguard Worker     tcu::RGBA threshold                   = renderTarget.getPixelFormat().getColorThreshold() + tcu::RGBA(4, 4, 4, 4);
436*35238bceSAndroid Build Coastguard Worker     bool isOk                             = true;
437*35238bceSAndroid Build Coastguard Worker 
438*35238bceSAndroid Build Coastguard Worker     vector<tcu::Vec2> positions;
439*35238bceSAndroid Build Coastguard Worker     vector<uint16_t> indices;
440*35238bceSAndroid Build Coastguard Worker 
441*35238bceSAndroid Build Coastguard Worker     tcu::Surface rendered;
442*35238bceSAndroid Build Coastguard Worker     tcu::Surface reference;
443*35238bceSAndroid Build Coastguard Worker 
444*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numBytes >= numBytesInQuad); // Can't render full quad with smaller buffers.
445*35238bceSAndroid Build Coastguard Worker 
446*35238bceSAndroid Build Coastguard Worker     computePositions(positions, maxQuadsX, maxQuadsY);
447*35238bceSAndroid Build Coastguard Worker     computeIndices(indices, maxQuadsX, maxQuadsY);
448*35238bceSAndroid Build Coastguard Worker 
449*35238bceSAndroid Build Coastguard Worker     // Reset buffer bindings.
450*35238bceSAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
451*35238bceSAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, 0);
452*35238bceSAndroid Build Coastguard Worker 
453*35238bceSAndroid Build Coastguard Worker     // Setup rendering state.
454*35238bceSAndroid Build Coastguard Worker     glViewport(0, 0, maxQuadsX * VERIFY_QUAD_SIZE, maxQuadsY * VERIFY_QUAD_SIZE);
455*35238bceSAndroid Build Coastguard Worker     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
456*35238bceSAndroid Build Coastguard Worker     glUseProgram(program);
457*35238bceSAndroid Build Coastguard Worker     glEnableVertexAttribArray(m_posLoc);
458*35238bceSAndroid Build Coastguard Worker     glVertexAttribPointer(m_posLoc, 2, GL_FLOAT, GL_FALSE, 0, &positions[0]);
459*35238bceSAndroid Build Coastguard Worker     glEnableVertexAttribArray(m_byteVecLoc);
460*35238bceSAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, buffer);
461*35238bceSAndroid Build Coastguard Worker 
462*35238bceSAndroid Build Coastguard Worker     while (numVerified < numBytes)
463*35238bceSAndroid Build Coastguard Worker     {
464*35238bceSAndroid Build Coastguard Worker         int numRemaining     = numBytes - numVerified;
465*35238bceSAndroid Build Coastguard Worker         bool isLeftoverBatch = numRemaining < numBytesInQuad;
466*35238bceSAndroid Build Coastguard Worker         int numBytesToVerify =
467*35238bceSAndroid Build Coastguard Worker             isLeftoverBatch ? numBytesInQuad :
468*35238bceSAndroid Build Coastguard Worker                               de::min(maxQuadsPerBatch * numBytesInQuad, numRemaining - numRemaining % numBytesInQuad);
469*35238bceSAndroid Build Coastguard Worker         int curOffset       = isLeftoverBatch ? (numBytes - numBytesInQuad) : numVerified;
470*35238bceSAndroid Build Coastguard Worker         int numQuads        = numBytesToVerify / numBytesInQuad;
471*35238bceSAndroid Build Coastguard Worker         int numCols         = de::min(maxQuadsX, numQuads);
472*35238bceSAndroid Build Coastguard Worker         int numRows         = numQuads / maxQuadsX + (numQuads % maxQuadsX != 0 ? 1 : 0);
473*35238bceSAndroid Build Coastguard Worker         string imageSetDesc = string("Bytes ") + de::toString(offset + curOffset) + " to " +
474*35238bceSAndroid Build Coastguard Worker                               de::toString(offset + curOffset + numBytesToVerify - 1);
475*35238bceSAndroid Build Coastguard Worker 
476*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(numBytesToVerify > 0 && numBytesToVerify % numBytesInQuad == 0);
477*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(de::inBounds(curOffset, 0, numBytes));
478*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(de::inRange(curOffset + numBytesToVerify, curOffset, numBytes));
479*35238bceSAndroid Build Coastguard Worker 
480*35238bceSAndroid Build Coastguard Worker         // Render batch.
481*35238bceSAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
482*35238bceSAndroid Build Coastguard Worker         glVertexAttribPointer(m_byteVecLoc, 3, GL_UNSIGNED_BYTE, GL_TRUE, 0,
483*35238bceSAndroid Build Coastguard Worker                               (const glw::GLvoid *)(uintptr_t)(offset + curOffset));
484*35238bceSAndroid Build Coastguard Worker         glDrawElements(GL_TRIANGLES, numQuads * 6, GL_UNSIGNED_SHORT, &indices[0]);
485*35238bceSAndroid Build Coastguard Worker 
486*35238bceSAndroid Build Coastguard Worker         renderQuadGridReference(reference, numQuads, numCols, refPtr + offset + curOffset);
487*35238bceSAndroid Build Coastguard Worker 
488*35238bceSAndroid Build Coastguard Worker         rendered.setSize(numCols * VERIFY_QUAD_SIZE, numRows * VERIFY_QUAD_SIZE);
489*35238bceSAndroid Build Coastguard Worker         glu::readPixels(m_context.getRenderContext(), 0, 0, rendered.getAccess());
490*35238bceSAndroid Build Coastguard Worker 
491*35238bceSAndroid Build Coastguard Worker         if (!tcu::pixelThresholdCompare(m_context.getTestContext().getLog(), "RenderResult", imageSetDesc.c_str(),
492*35238bceSAndroid Build Coastguard Worker                                         reference, rendered, threshold, tcu::COMPARE_LOG_RESULT))
493*35238bceSAndroid Build Coastguard Worker         {
494*35238bceSAndroid Build Coastguard Worker             isOk = false;
495*35238bceSAndroid Build Coastguard Worker             break;
496*35238bceSAndroid Build Coastguard Worker         }
497*35238bceSAndroid Build Coastguard Worker 
498*35238bceSAndroid Build Coastguard Worker         numVerified += isLeftoverBatch ? numRemaining : numBytesToVerify;
499*35238bceSAndroid Build Coastguard Worker     }
500*35238bceSAndroid Build Coastguard Worker 
501*35238bceSAndroid Build Coastguard Worker     glDisableVertexAttribArray(m_posLoc);
502*35238bceSAndroid Build Coastguard Worker     glDisableVertexAttribArray(m_byteVecLoc);
503*35238bceSAndroid Build Coastguard Worker 
504*35238bceSAndroid Build Coastguard Worker     return isOk;
505*35238bceSAndroid Build Coastguard Worker }
506*35238bceSAndroid Build Coastguard Worker 
507*35238bceSAndroid Build Coastguard Worker // IndexArrayVerifier
508*35238bceSAndroid Build Coastguard Worker 
IndexArrayVerifier(Context & context)509*35238bceSAndroid Build Coastguard Worker IndexArrayVerifier::IndexArrayVerifier(Context &context)
510*35238bceSAndroid Build Coastguard Worker     : BufferVerifierBase(context)
511*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
512*35238bceSAndroid Build Coastguard Worker     , m_posLoc(0)
513*35238bceSAndroid Build Coastguard Worker     , m_colorLoc(0)
514*35238bceSAndroid Build Coastguard Worker {
515*35238bceSAndroid Build Coastguard Worker     m_program = new glu::ShaderProgram(m_context.getRenderContext(),
516*35238bceSAndroid Build Coastguard Worker                                        glu::makeVtxFragSources("attribute highp vec2 a_position;\n"
517*35238bceSAndroid Build Coastguard Worker                                                                "attribute mediump vec3 a_color;\n"
518*35238bceSAndroid Build Coastguard Worker                                                                "varying mediump vec3 v_color;\n"
519*35238bceSAndroid Build Coastguard Worker                                                                "void main (void)\n"
520*35238bceSAndroid Build Coastguard Worker                                                                "{\n"
521*35238bceSAndroid Build Coastguard Worker                                                                "    gl_Position = vec4(a_position, 0.0, 1.0);\n"
522*35238bceSAndroid Build Coastguard Worker                                                                "    v_color = a_color;\n"
523*35238bceSAndroid Build Coastguard Worker                                                                "}\n",
524*35238bceSAndroid Build Coastguard Worker 
525*35238bceSAndroid Build Coastguard Worker                                                                "varying mediump vec3 v_color;\n"
526*35238bceSAndroid Build Coastguard Worker                                                                "void main (void)\n"
527*35238bceSAndroid Build Coastguard Worker                                                                "{\n"
528*35238bceSAndroid Build Coastguard Worker                                                                "    gl_FragColor = vec4(v_color, 1.0);\n"
529*35238bceSAndroid Build Coastguard Worker                                                                "}\n"));
530*35238bceSAndroid Build Coastguard Worker 
531*35238bceSAndroid Build Coastguard Worker     if (!m_program->isOk())
532*35238bceSAndroid Build Coastguard Worker     {
533*35238bceSAndroid Build Coastguard Worker         m_context.getTestContext().getLog() << *m_program;
534*35238bceSAndroid Build Coastguard Worker         delete m_program;
535*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Compile failed");
536*35238bceSAndroid Build Coastguard Worker     }
537*35238bceSAndroid Build Coastguard Worker 
538*35238bceSAndroid Build Coastguard Worker     const glw::Functions &funcs = context.getRenderContext().getFunctions();
539*35238bceSAndroid Build Coastguard Worker     m_posLoc                    = funcs.getAttribLocation(m_program->getProgram(), "a_position");
540*35238bceSAndroid Build Coastguard Worker     m_colorLoc                  = funcs.getAttribLocation(m_program->getProgram(), "a_color");
541*35238bceSAndroid Build Coastguard Worker }
542*35238bceSAndroid Build Coastguard Worker 
~IndexArrayVerifier(void)543*35238bceSAndroid Build Coastguard Worker IndexArrayVerifier::~IndexArrayVerifier(void)
544*35238bceSAndroid Build Coastguard Worker {
545*35238bceSAndroid Build Coastguard Worker     delete m_program;
546*35238bceSAndroid Build Coastguard Worker }
547*35238bceSAndroid Build Coastguard Worker 
computeIndexVerifierPositions(std::vector<tcu::Vec2> & dst)548*35238bceSAndroid Build Coastguard Worker static void computeIndexVerifierPositions(std::vector<tcu::Vec2> &dst)
549*35238bceSAndroid Build Coastguard Worker {
550*35238bceSAndroid Build Coastguard Worker     const int numPosX = 16;
551*35238bceSAndroid Build Coastguard Worker     const int numPosY = 16;
552*35238bceSAndroid Build Coastguard Worker 
553*35238bceSAndroid Build Coastguard Worker     dst.resize(numPosX * numPosY);
554*35238bceSAndroid Build Coastguard Worker 
555*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < numPosY; y++)
556*35238bceSAndroid Build Coastguard Worker     {
557*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < numPosX; x++)
558*35238bceSAndroid Build Coastguard Worker         {
559*35238bceSAndroid Build Coastguard Worker             float xf = float(x) / float(numPosX - 1);
560*35238bceSAndroid Build Coastguard Worker             float yf = float(y) / float(numPosY - 1);
561*35238bceSAndroid Build Coastguard Worker 
562*35238bceSAndroid Build Coastguard Worker             dst[y * numPosX + x] = tcu::Vec2(2.0f * xf - 1.0f, 2.0f * yf - 1.0f);
563*35238bceSAndroid Build Coastguard Worker         }
564*35238bceSAndroid Build Coastguard Worker     }
565*35238bceSAndroid Build Coastguard Worker }
566*35238bceSAndroid Build Coastguard Worker 
computeIndexVerifierColors(std::vector<tcu::Vec3> & dst)567*35238bceSAndroid Build Coastguard Worker static void computeIndexVerifierColors(std::vector<tcu::Vec3> &dst)
568*35238bceSAndroid Build Coastguard Worker {
569*35238bceSAndroid Build Coastguard Worker     const int numColors = 256;
570*35238bceSAndroid Build Coastguard Worker     const float minVal  = 0.1f;
571*35238bceSAndroid Build Coastguard Worker     const float maxVal  = 0.5f;
572*35238bceSAndroid Build Coastguard Worker     de::Random rnd(0xabc231);
573*35238bceSAndroid Build Coastguard Worker 
574*35238bceSAndroid Build Coastguard Worker     dst.resize(numColors);
575*35238bceSAndroid Build Coastguard Worker 
576*35238bceSAndroid Build Coastguard Worker     for (std::vector<tcu::Vec3>::iterator i = dst.begin(); i != dst.end(); ++i)
577*35238bceSAndroid Build Coastguard Worker     {
578*35238bceSAndroid Build Coastguard Worker         i->x() = rnd.getFloat(minVal, maxVal);
579*35238bceSAndroid Build Coastguard Worker         i->y() = rnd.getFloat(minVal, maxVal);
580*35238bceSAndroid Build Coastguard Worker         i->z() = rnd.getFloat(minVal, maxVal);
581*35238bceSAndroid Build Coastguard Worker     }
582*35238bceSAndroid Build Coastguard Worker }
583*35238bceSAndroid Build Coastguard Worker 
584*35238bceSAndroid Build Coastguard Worker template <typename T>
execVertexFetch(T * dst,const T * src,const uint8_t * indices,int numIndices)585*35238bceSAndroid Build Coastguard Worker static void execVertexFetch(T *dst, const T *src, const uint8_t *indices, int numIndices)
586*35238bceSAndroid Build Coastguard Worker {
587*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < numIndices; ++i)
588*35238bceSAndroid Build Coastguard Worker         dst[i] = src[indices[i]];
589*35238bceSAndroid Build Coastguard Worker }
590*35238bceSAndroid Build Coastguard Worker 
verify(uint32_t buffer,const uint8_t * refPtr,int offset,int numBytes)591*35238bceSAndroid Build Coastguard Worker bool IndexArrayVerifier::verify(uint32_t buffer, const uint8_t *refPtr, int offset, int numBytes)
592*35238bceSAndroid Build Coastguard Worker {
593*35238bceSAndroid Build Coastguard Worker     const tcu::RenderTarget &renderTarget = m_context.getRenderContext().getRenderTarget();
594*35238bceSAndroid Build Coastguard Worker     const int viewportW                   = de::min<int>(INDEX_ARRAY_DRAW_VIEWPORT_WIDTH, renderTarget.getWidth());
595*35238bceSAndroid Build Coastguard Worker     const int viewportH                   = de::min<int>(INDEX_ARRAY_DRAW_VIEWPORT_HEIGHT, renderTarget.getHeight());
596*35238bceSAndroid Build Coastguard Worker     const int minBytesPerBatch            = 2;
597*35238bceSAndroid Build Coastguard Worker     const tcu::RGBA threshold(0, 0, 0, 0);
598*35238bceSAndroid Build Coastguard Worker 
599*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec2> positions;
600*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec3> colors;
601*35238bceSAndroid Build Coastguard Worker 
602*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec2> fetchedPos(MAX_LINES_PER_INDEX_ARRAY_DRAW + 1);
603*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec3> fetchedColor(MAX_LINES_PER_INDEX_ARRAY_DRAW + 1);
604*35238bceSAndroid Build Coastguard Worker 
605*35238bceSAndroid Build Coastguard Worker     tcu::Surface indexBufferImg(viewportW, viewportH);
606*35238bceSAndroid Build Coastguard Worker     tcu::Surface referenceImg(viewportW, viewportH);
607*35238bceSAndroid Build Coastguard Worker 
608*35238bceSAndroid Build Coastguard Worker     int numVerified = 0;
609*35238bceSAndroid Build Coastguard Worker     bool isOk       = true;
610*35238bceSAndroid Build Coastguard Worker 
611*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(sizeof(tcu::Vec2) == sizeof(float) * 2);
612*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(sizeof(tcu::Vec3) == sizeof(float) * 3);
613*35238bceSAndroid Build Coastguard Worker 
614*35238bceSAndroid Build Coastguard Worker     computeIndexVerifierPositions(positions);
615*35238bceSAndroid Build Coastguard Worker     computeIndexVerifierColors(colors);
616*35238bceSAndroid Build Coastguard Worker 
617*35238bceSAndroid Build Coastguard Worker     // Reset buffer bindings.
618*35238bceSAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, 0);
619*35238bceSAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
620*35238bceSAndroid Build Coastguard Worker 
621*35238bceSAndroid Build Coastguard Worker     // Setup rendering state.
622*35238bceSAndroid Build Coastguard Worker     glViewport(0, 0, viewportW, viewportH);
623*35238bceSAndroid Build Coastguard Worker     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
624*35238bceSAndroid Build Coastguard Worker     glUseProgram(m_program->getProgram());
625*35238bceSAndroid Build Coastguard Worker     glEnableVertexAttribArray(m_posLoc);
626*35238bceSAndroid Build Coastguard Worker     glEnableVertexAttribArray(m_colorLoc);
627*35238bceSAndroid Build Coastguard Worker     glEnable(GL_BLEND);
628*35238bceSAndroid Build Coastguard Worker     glBlendFunc(GL_ONE, GL_ONE);
629*35238bceSAndroid Build Coastguard Worker     glBlendEquation(GL_FUNC_ADD);
630*35238bceSAndroid Build Coastguard Worker 
631*35238bceSAndroid Build Coastguard Worker     while (numVerified < numBytes)
632*35238bceSAndroid Build Coastguard Worker     {
633*35238bceSAndroid Build Coastguard Worker         int numRemaining     = numBytes - numVerified;
634*35238bceSAndroid Build Coastguard Worker         bool isLeftoverBatch = numRemaining < minBytesPerBatch;
635*35238bceSAndroid Build Coastguard Worker         int numBytesToVerify =
636*35238bceSAndroid Build Coastguard Worker             isLeftoverBatch ? minBytesPerBatch : de::min(MAX_LINES_PER_INDEX_ARRAY_DRAW + 1, numRemaining);
637*35238bceSAndroid Build Coastguard Worker         int curOffset       = isLeftoverBatch ? (numBytes - minBytesPerBatch) : numVerified;
638*35238bceSAndroid Build Coastguard Worker         string imageSetDesc = string("Bytes ") + de::toString(offset + curOffset) + " to " +
639*35238bceSAndroid Build Coastguard Worker                               de::toString(offset + curOffset + numBytesToVerify - 1);
640*35238bceSAndroid Build Coastguard Worker 
641*35238bceSAndroid Build Coastguard Worker         // Step 1: Render using index buffer.
642*35238bceSAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
643*35238bceSAndroid Build Coastguard Worker         glVertexAttribPointer(m_posLoc, 2, GL_FLOAT, GL_FALSE, 0, &positions[0]);
644*35238bceSAndroid Build Coastguard Worker         glVertexAttribPointer(m_colorLoc, 3, GL_FLOAT, GL_FALSE, 0, &colors[0]);
645*35238bceSAndroid Build Coastguard Worker         glDrawElements(GL_LINE_STRIP, numBytesToVerify, GL_UNSIGNED_BYTE, (void *)(uintptr_t)(offset + curOffset));
646*35238bceSAndroid Build Coastguard Worker         glu::readPixels(m_context.getRenderContext(), 0, 0, indexBufferImg.getAccess());
647*35238bceSAndroid Build Coastguard Worker 
648*35238bceSAndroid Build Coastguard Worker         // Step 2: Do manual fetch and render without index buffer.
649*35238bceSAndroid Build Coastguard Worker         execVertexFetch(&fetchedPos[0], &positions[0], refPtr + offset + curOffset, numBytesToVerify);
650*35238bceSAndroid Build Coastguard Worker         execVertexFetch(&fetchedColor[0], &colors[0], refPtr + offset + curOffset, numBytesToVerify);
651*35238bceSAndroid Build Coastguard Worker 
652*35238bceSAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
653*35238bceSAndroid Build Coastguard Worker         glVertexAttribPointer(m_posLoc, 2, GL_FLOAT, GL_FALSE, 0, &fetchedPos[0]);
654*35238bceSAndroid Build Coastguard Worker         glVertexAttribPointer(m_colorLoc, 3, GL_FLOAT, GL_FALSE, 0, &fetchedColor[0]);
655*35238bceSAndroid Build Coastguard Worker         glDrawArrays(GL_LINE_STRIP, 0, numBytesToVerify);
656*35238bceSAndroid Build Coastguard Worker         glu::readPixels(m_context.getRenderContext(), 0, 0, referenceImg.getAccess());
657*35238bceSAndroid Build Coastguard Worker 
658*35238bceSAndroid Build Coastguard Worker         if (!tcu::pixelThresholdCompare(m_context.getTestContext().getLog(), "RenderResult", imageSetDesc.c_str(),
659*35238bceSAndroid Build Coastguard Worker                                         referenceImg, indexBufferImg, threshold, tcu::COMPARE_LOG_RESULT))
660*35238bceSAndroid Build Coastguard Worker         {
661*35238bceSAndroid Build Coastguard Worker             isOk = false;
662*35238bceSAndroid Build Coastguard Worker             break;
663*35238bceSAndroid Build Coastguard Worker         }
664*35238bceSAndroid Build Coastguard Worker 
665*35238bceSAndroid Build Coastguard Worker         numVerified += isLeftoverBatch ? numRemaining : numBytesToVerify;
666*35238bceSAndroid Build Coastguard Worker     }
667*35238bceSAndroid Build Coastguard Worker 
668*35238bceSAndroid Build Coastguard Worker     return isOk;
669*35238bceSAndroid Build Coastguard Worker }
670*35238bceSAndroid Build Coastguard Worker 
671*35238bceSAndroid Build Coastguard Worker } // namespace BufferTestUtil
672*35238bceSAndroid Build Coastguard Worker } // namespace Functional
673*35238bceSAndroid Build Coastguard Worker } // namespace gles2
674*35238bceSAndroid Build Coastguard Worker } // namespace deqp
675