xref: /aosp_15_r20/external/deqp/modules/glshared/glsBufferTestUtil.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL (ES) 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 "glsBufferTestUtil.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 "tcuTestLog.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "deMemory.h"
38*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "deArrayUtil.hpp"
40*35238bceSAndroid Build Coastguard Worker 
41*35238bceSAndroid Build Coastguard Worker #include <algorithm>
42*35238bceSAndroid Build Coastguard Worker 
43*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
44*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
45*35238bceSAndroid Build Coastguard Worker 
46*35238bceSAndroid Build Coastguard Worker namespace deqp
47*35238bceSAndroid Build Coastguard Worker {
48*35238bceSAndroid Build Coastguard Worker namespace gls
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 using std::set;
62*35238bceSAndroid Build Coastguard Worker using std::string;
63*35238bceSAndroid Build Coastguard Worker using std::vector;
64*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
65*35238bceSAndroid Build Coastguard Worker 
66*35238bceSAndroid Build Coastguard Worker // Helper functions.
67*35238bceSAndroid Build Coastguard Worker 
fillWithRandomBytes(uint8_t * ptr,int numBytes,uint32_t seed)68*35238bceSAndroid Build Coastguard Worker void fillWithRandomBytes(uint8_t *ptr, int numBytes, uint32_t seed)
69*35238bceSAndroid Build Coastguard Worker {
70*35238bceSAndroid Build Coastguard Worker     std::copy(tcu::RandomValueIterator<uint8_t>::begin(seed, numBytes), tcu::RandomValueIterator<uint8_t>::end(), ptr);
71*35238bceSAndroid Build Coastguard Worker }
72*35238bceSAndroid Build Coastguard Worker 
compareByteArrays(tcu::TestLog & log,const uint8_t * resPtr,const uint8_t * refPtr,int numBytes)73*35238bceSAndroid Build Coastguard Worker bool compareByteArrays(tcu::TestLog &log, const uint8_t *resPtr, const uint8_t *refPtr, int numBytes)
74*35238bceSAndroid Build Coastguard Worker {
75*35238bceSAndroid Build Coastguard Worker     bool isOk              = true;
76*35238bceSAndroid Build Coastguard Worker     const int maxSpanLen   = 8;
77*35238bceSAndroid Build Coastguard Worker     const int maxDiffSpans = 4;
78*35238bceSAndroid Build Coastguard Worker     int numDiffSpans       = 0;
79*35238bceSAndroid Build Coastguard Worker     int diffSpanStart      = -1;
80*35238bceSAndroid Build Coastguard Worker     int ndx                = 0;
81*35238bceSAndroid Build Coastguard Worker 
82*35238bceSAndroid Build Coastguard Worker     log << TestLog::Section("Verify", "Verification result");
83*35238bceSAndroid Build Coastguard Worker 
84*35238bceSAndroid Build Coastguard Worker     for (; ndx < numBytes; ndx++)
85*35238bceSAndroid Build Coastguard Worker     {
86*35238bceSAndroid Build Coastguard Worker         if (resPtr[ndx] != refPtr[ndx])
87*35238bceSAndroid Build Coastguard Worker         {
88*35238bceSAndroid Build Coastguard Worker             if (diffSpanStart < 0)
89*35238bceSAndroid Build Coastguard Worker                 diffSpanStart = ndx;
90*35238bceSAndroid Build Coastguard Worker 
91*35238bceSAndroid Build Coastguard Worker             isOk = false;
92*35238bceSAndroid Build Coastguard Worker         }
93*35238bceSAndroid Build Coastguard Worker         else if (diffSpanStart >= 0)
94*35238bceSAndroid Build Coastguard Worker         {
95*35238bceSAndroid Build Coastguard Worker             if (numDiffSpans < maxDiffSpans)
96*35238bceSAndroid Build Coastguard Worker             {
97*35238bceSAndroid Build Coastguard Worker                 int len      = ndx - diffSpanStart;
98*35238bceSAndroid Build Coastguard Worker                 int printLen = de::min(len, maxSpanLen);
99*35238bceSAndroid Build Coastguard Worker 
100*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message << len << " byte difference at offset " << diffSpanStart << "\n"
101*35238bceSAndroid Build Coastguard Worker                     << "  expected "
102*35238bceSAndroid Build Coastguard Worker                     << tcu::formatArray(tcu::Format::HexIterator<uint8_t>(refPtr + diffSpanStart),
103*35238bceSAndroid Build Coastguard Worker                                         tcu::Format::HexIterator<uint8_t>(refPtr + diffSpanStart + printLen))
104*35238bceSAndroid Build Coastguard Worker                     << "\n"
105*35238bceSAndroid Build Coastguard Worker                     << "  got "
106*35238bceSAndroid Build Coastguard Worker                     << tcu::formatArray(tcu::Format::HexIterator<uint8_t>(resPtr + diffSpanStart),
107*35238bceSAndroid Build Coastguard Worker                                         tcu::Format::HexIterator<uint8_t>(resPtr + diffSpanStart + printLen))
108*35238bceSAndroid Build Coastguard Worker                     << TestLog::EndMessage;
109*35238bceSAndroid Build Coastguard Worker             }
110*35238bceSAndroid Build Coastguard Worker             else
111*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message << "(output too long, truncated)" << TestLog::EndMessage;
112*35238bceSAndroid Build Coastguard Worker 
113*35238bceSAndroid Build Coastguard Worker             numDiffSpans += 1;
114*35238bceSAndroid Build Coastguard Worker             diffSpanStart = -1;
115*35238bceSAndroid Build Coastguard Worker         }
116*35238bceSAndroid Build Coastguard Worker     }
117*35238bceSAndroid Build Coastguard Worker 
118*35238bceSAndroid Build Coastguard Worker     if (diffSpanStart >= 0)
119*35238bceSAndroid Build Coastguard Worker     {
120*35238bceSAndroid Build Coastguard Worker         if (numDiffSpans < maxDiffSpans)
121*35238bceSAndroid Build Coastguard Worker         {
122*35238bceSAndroid Build Coastguard Worker             int len      = ndx - diffSpanStart;
123*35238bceSAndroid Build Coastguard Worker             int printLen = de::min(len, maxSpanLen);
124*35238bceSAndroid Build Coastguard Worker 
125*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << len << " byte difference at offset " << diffSpanStart << "\n"
126*35238bceSAndroid Build Coastguard Worker                 << "  expected "
127*35238bceSAndroid Build Coastguard Worker                 << tcu::formatArray(tcu::Format::HexIterator<uint8_t>(refPtr + diffSpanStart),
128*35238bceSAndroid Build Coastguard Worker                                     tcu::Format::HexIterator<uint8_t>(refPtr + diffSpanStart + printLen))
129*35238bceSAndroid Build Coastguard Worker                 << "\n"
130*35238bceSAndroid Build Coastguard Worker                 << "  got "
131*35238bceSAndroid Build Coastguard Worker                 << tcu::formatArray(tcu::Format::HexIterator<uint8_t>(resPtr + diffSpanStart),
132*35238bceSAndroid Build Coastguard Worker                                     tcu::Format::HexIterator<uint8_t>(resPtr + diffSpanStart + printLen))
133*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
134*35238bceSAndroid Build Coastguard Worker         }
135*35238bceSAndroid Build Coastguard Worker         else
136*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "(output too long, truncated)" << TestLog::EndMessage;
137*35238bceSAndroid Build Coastguard Worker     }
138*35238bceSAndroid Build Coastguard Worker 
139*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << (isOk ? "Verification passed." : "Verification FAILED!") << TestLog::EndMessage;
140*35238bceSAndroid Build Coastguard Worker     log << TestLog::EndSection;
141*35238bceSAndroid Build Coastguard Worker 
142*35238bceSAndroid Build Coastguard Worker     return isOk;
143*35238bceSAndroid Build Coastguard Worker }
144*35238bceSAndroid Build Coastguard Worker 
getBufferTargetName(uint32_t target)145*35238bceSAndroid Build Coastguard Worker const char *getBufferTargetName(uint32_t target)
146*35238bceSAndroid Build Coastguard Worker {
147*35238bceSAndroid Build Coastguard Worker     switch (target)
148*35238bceSAndroid Build Coastguard Worker     {
149*35238bceSAndroid Build Coastguard Worker     case GL_ARRAY_BUFFER:
150*35238bceSAndroid Build Coastguard Worker         return "array";
151*35238bceSAndroid Build Coastguard Worker     case GL_COPY_READ_BUFFER:
152*35238bceSAndroid Build Coastguard Worker         return "copy_read";
153*35238bceSAndroid Build Coastguard Worker     case GL_COPY_WRITE_BUFFER:
154*35238bceSAndroid Build Coastguard Worker         return "copy_write";
155*35238bceSAndroid Build Coastguard Worker     case GL_ELEMENT_ARRAY_BUFFER:
156*35238bceSAndroid Build Coastguard Worker         return "element_array";
157*35238bceSAndroid Build Coastguard Worker     case GL_PIXEL_PACK_BUFFER:
158*35238bceSAndroid Build Coastguard Worker         return "pixel_pack";
159*35238bceSAndroid Build Coastguard Worker     case GL_PIXEL_UNPACK_BUFFER:
160*35238bceSAndroid Build Coastguard Worker         return "pixel_unpack";
161*35238bceSAndroid Build Coastguard Worker     case GL_TEXTURE_BUFFER:
162*35238bceSAndroid Build Coastguard Worker         return "texture";
163*35238bceSAndroid Build Coastguard Worker     case GL_TRANSFORM_FEEDBACK_BUFFER:
164*35238bceSAndroid Build Coastguard Worker         return "transform_feedback";
165*35238bceSAndroid Build Coastguard Worker     case GL_UNIFORM_BUFFER:
166*35238bceSAndroid Build Coastguard Worker         return "uniform";
167*35238bceSAndroid Build Coastguard Worker     default:
168*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
169*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
170*35238bceSAndroid Build Coastguard Worker     }
171*35238bceSAndroid Build Coastguard Worker }
172*35238bceSAndroid Build Coastguard Worker 
getUsageHintName(uint32_t hint)173*35238bceSAndroid Build Coastguard Worker const char *getUsageHintName(uint32_t hint)
174*35238bceSAndroid Build Coastguard Worker {
175*35238bceSAndroid Build Coastguard Worker     switch (hint)
176*35238bceSAndroid Build Coastguard Worker     {
177*35238bceSAndroid Build Coastguard Worker     case GL_STREAM_DRAW:
178*35238bceSAndroid Build Coastguard Worker         return "stream_draw";
179*35238bceSAndroid Build Coastguard Worker     case GL_STREAM_READ:
180*35238bceSAndroid Build Coastguard Worker         return "stream_read";
181*35238bceSAndroid Build Coastguard Worker     case GL_STREAM_COPY:
182*35238bceSAndroid Build Coastguard Worker         return "stream_copy";
183*35238bceSAndroid Build Coastguard Worker     case GL_STATIC_DRAW:
184*35238bceSAndroid Build Coastguard Worker         return "static_draw";
185*35238bceSAndroid Build Coastguard Worker     case GL_STATIC_READ:
186*35238bceSAndroid Build Coastguard Worker         return "static_read";
187*35238bceSAndroid Build Coastguard Worker     case GL_STATIC_COPY:
188*35238bceSAndroid Build Coastguard Worker         return "static_copy";
189*35238bceSAndroid Build Coastguard Worker     case GL_DYNAMIC_DRAW:
190*35238bceSAndroid Build Coastguard Worker         return "dynamic_draw";
191*35238bceSAndroid Build Coastguard Worker     case GL_DYNAMIC_READ:
192*35238bceSAndroid Build Coastguard Worker         return "dynamic_read";
193*35238bceSAndroid Build Coastguard Worker     case GL_DYNAMIC_COPY:
194*35238bceSAndroid Build Coastguard Worker         return "dynamic_copy";
195*35238bceSAndroid Build Coastguard Worker     default:
196*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
197*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
198*35238bceSAndroid Build Coastguard Worker     }
199*35238bceSAndroid Build Coastguard Worker }
200*35238bceSAndroid Build Coastguard Worker 
201*35238bceSAndroid Build Coastguard Worker // BufferCase
202*35238bceSAndroid Build Coastguard Worker 
BufferCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description)203*35238bceSAndroid Build Coastguard Worker BufferCase::BufferCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
204*35238bceSAndroid Build Coastguard Worker                        const char *description)
205*35238bceSAndroid Build Coastguard Worker     : TestCase(testCtx, name, description)
206*35238bceSAndroid Build Coastguard Worker     , CallLogWrapper(renderCtx.getFunctions(), testCtx.getLog())
207*35238bceSAndroid Build Coastguard Worker     , m_renderCtx(renderCtx)
208*35238bceSAndroid Build Coastguard Worker {
209*35238bceSAndroid Build Coastguard Worker }
210*35238bceSAndroid Build Coastguard Worker 
~BufferCase(void)211*35238bceSAndroid Build Coastguard Worker BufferCase::~BufferCase(void)
212*35238bceSAndroid Build Coastguard Worker {
213*35238bceSAndroid Build Coastguard Worker     enableLogging(false);
214*35238bceSAndroid Build Coastguard Worker     BufferCase::deinit();
215*35238bceSAndroid Build Coastguard Worker }
216*35238bceSAndroid Build Coastguard Worker 
init(void)217*35238bceSAndroid Build Coastguard Worker void BufferCase::init(void)
218*35238bceSAndroid Build Coastguard Worker {
219*35238bceSAndroid Build Coastguard Worker     enableLogging(true);
220*35238bceSAndroid Build Coastguard Worker }
221*35238bceSAndroid Build Coastguard Worker 
deinit(void)222*35238bceSAndroid Build Coastguard Worker void BufferCase::deinit(void)
223*35238bceSAndroid Build Coastguard Worker {
224*35238bceSAndroid Build Coastguard Worker     for (set<uint32_t>::const_iterator bufIter = m_allocatedBuffers.begin(); bufIter != m_allocatedBuffers.end();
225*35238bceSAndroid Build Coastguard Worker          bufIter++)
226*35238bceSAndroid Build Coastguard Worker         glDeleteBuffers(1, &(*bufIter));
227*35238bceSAndroid Build Coastguard Worker }
228*35238bceSAndroid Build Coastguard Worker 
genBuffer(void)229*35238bceSAndroid Build Coastguard Worker uint32_t BufferCase::genBuffer(void)
230*35238bceSAndroid Build Coastguard Worker {
231*35238bceSAndroid Build Coastguard Worker     uint32_t buf = 0;
232*35238bceSAndroid Build Coastguard Worker     glGenBuffers(1, &buf);
233*35238bceSAndroid Build Coastguard Worker     if (buf != 0)
234*35238bceSAndroid Build Coastguard Worker     {
235*35238bceSAndroid Build Coastguard Worker         try
236*35238bceSAndroid Build Coastguard Worker         {
237*35238bceSAndroid Build Coastguard Worker             m_allocatedBuffers.insert(buf);
238*35238bceSAndroid Build Coastguard Worker         }
239*35238bceSAndroid Build Coastguard Worker         catch (const std::exception &)
240*35238bceSAndroid Build Coastguard Worker         {
241*35238bceSAndroid Build Coastguard Worker             glDeleteBuffers(1, &buf);
242*35238bceSAndroid Build Coastguard Worker             throw;
243*35238bceSAndroid Build Coastguard Worker         }
244*35238bceSAndroid Build Coastguard Worker     }
245*35238bceSAndroid Build Coastguard Worker     return buf;
246*35238bceSAndroid Build Coastguard Worker }
247*35238bceSAndroid Build Coastguard Worker 
deleteBuffer(uint32_t buffer)248*35238bceSAndroid Build Coastguard Worker void BufferCase::deleteBuffer(uint32_t buffer)
249*35238bceSAndroid Build Coastguard Worker {
250*35238bceSAndroid Build Coastguard Worker     glDeleteBuffers(1, &buffer);
251*35238bceSAndroid Build Coastguard Worker     m_allocatedBuffers.erase(buffer);
252*35238bceSAndroid Build Coastguard Worker }
253*35238bceSAndroid Build Coastguard Worker 
checkError(void)254*35238bceSAndroid Build Coastguard Worker void BufferCase::checkError(void)
255*35238bceSAndroid Build Coastguard Worker {
256*35238bceSAndroid Build Coastguard Worker     glw::GLenum err = glGetError();
257*35238bceSAndroid Build Coastguard Worker     if (err != GL_NO_ERROR)
258*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError(string("Got ") + glu::getErrorStr(err).toString());
259*35238bceSAndroid Build Coastguard Worker }
260*35238bceSAndroid Build Coastguard Worker 
261*35238bceSAndroid Build Coastguard Worker // ReferenceBuffer
262*35238bceSAndroid Build Coastguard Worker 
setSize(int numBytes)263*35238bceSAndroid Build Coastguard Worker void ReferenceBuffer::setSize(int numBytes)
264*35238bceSAndroid Build Coastguard Worker {
265*35238bceSAndroid Build Coastguard Worker     m_data.resize(numBytes);
266*35238bceSAndroid Build Coastguard Worker }
267*35238bceSAndroid Build Coastguard Worker 
setData(int numBytes,const uint8_t * bytes)268*35238bceSAndroid Build Coastguard Worker void ReferenceBuffer::setData(int numBytes, const uint8_t *bytes)
269*35238bceSAndroid Build Coastguard Worker {
270*35238bceSAndroid Build Coastguard Worker     m_data.resize(numBytes);
271*35238bceSAndroid Build Coastguard Worker     std::copy(bytes, bytes + numBytes, m_data.begin());
272*35238bceSAndroid Build Coastguard Worker }
273*35238bceSAndroid Build Coastguard Worker 
setSubData(int offset,int numBytes,const uint8_t * bytes)274*35238bceSAndroid Build Coastguard Worker void ReferenceBuffer::setSubData(int offset, int numBytes, const uint8_t *bytes)
275*35238bceSAndroid Build Coastguard Worker {
276*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inBounds(offset, 0, (int)m_data.size()) &&
277*35238bceSAndroid Build Coastguard Worker               de::inRange(offset + numBytes, offset, (int)m_data.size()));
278*35238bceSAndroid Build Coastguard Worker     std::copy(bytes, bytes + numBytes, m_data.begin() + offset);
279*35238bceSAndroid Build Coastguard Worker }
280*35238bceSAndroid Build Coastguard Worker 
281*35238bceSAndroid Build Coastguard Worker // BufferWriterBase
282*35238bceSAndroid Build Coastguard Worker 
BufferWriterBase(glu::RenderContext & renderCtx,tcu::TestLog & log)283*35238bceSAndroid Build Coastguard Worker BufferWriterBase::BufferWriterBase(glu::RenderContext &renderCtx, tcu::TestLog &log)
284*35238bceSAndroid Build Coastguard Worker     : CallLogWrapper(renderCtx.getFunctions(), log)
285*35238bceSAndroid Build Coastguard Worker     , m_renderCtx(renderCtx)
286*35238bceSAndroid Build Coastguard Worker {
287*35238bceSAndroid Build Coastguard Worker     enableLogging(true);
288*35238bceSAndroid Build Coastguard Worker }
289*35238bceSAndroid Build Coastguard Worker 
write(uint32_t buffer,int offset,int numBytes,const uint8_t * bytes,uint32_t targetHint)290*35238bceSAndroid Build Coastguard Worker void BufferWriterBase::write(uint32_t buffer, int offset, int numBytes, const uint8_t *bytes, uint32_t targetHint)
291*35238bceSAndroid Build Coastguard Worker {
292*35238bceSAndroid Build Coastguard Worker     DE_UNREF(targetHint);
293*35238bceSAndroid Build Coastguard Worker     write(buffer, offset, numBytes, bytes);
294*35238bceSAndroid Build Coastguard Worker }
295*35238bceSAndroid Build Coastguard Worker 
296*35238bceSAndroid Build Coastguard Worker // BufferWriter
297*35238bceSAndroid Build Coastguard Worker 
BufferWriter(glu::RenderContext & renderCtx,tcu::TestLog & log,WriteType writeType)298*35238bceSAndroid Build Coastguard Worker BufferWriter::BufferWriter(glu::RenderContext &renderCtx, tcu::TestLog &log, WriteType writeType) : m_writer(DE_NULL)
299*35238bceSAndroid Build Coastguard Worker {
300*35238bceSAndroid Build Coastguard Worker     switch (writeType)
301*35238bceSAndroid Build Coastguard Worker     {
302*35238bceSAndroid Build Coastguard Worker     case WRITE_BUFFER_SUB_DATA:
303*35238bceSAndroid Build Coastguard Worker         m_writer = new BufferSubDataWriter(renderCtx, log);
304*35238bceSAndroid Build Coastguard Worker         break;
305*35238bceSAndroid Build Coastguard Worker     case WRITE_BUFFER_WRITE_MAP:
306*35238bceSAndroid Build Coastguard Worker         m_writer = new BufferWriteMapWriter(renderCtx, log);
307*35238bceSAndroid Build Coastguard Worker         break;
308*35238bceSAndroid Build Coastguard Worker     default:
309*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Unsupported writer");
310*35238bceSAndroid Build Coastguard Worker     }
311*35238bceSAndroid Build Coastguard Worker }
312*35238bceSAndroid Build Coastguard Worker 
~BufferWriter(void)313*35238bceSAndroid Build Coastguard Worker BufferWriter::~BufferWriter(void)
314*35238bceSAndroid Build Coastguard Worker {
315*35238bceSAndroid Build Coastguard Worker     delete m_writer;
316*35238bceSAndroid Build Coastguard Worker }
317*35238bceSAndroid Build Coastguard Worker 
write(uint32_t buffer,int offset,int numBytes,const uint8_t * bytes)318*35238bceSAndroid Build Coastguard Worker void BufferWriter::write(uint32_t buffer, int offset, int numBytes, const uint8_t *bytes)
319*35238bceSAndroid Build Coastguard Worker {
320*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numBytes >= getMinSize());
321*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(offset % getAlignment() == 0);
322*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((offset + numBytes) % getAlignment() == 0);
323*35238bceSAndroid Build Coastguard Worker     return m_writer->write(buffer, offset, numBytes, bytes);
324*35238bceSAndroid Build Coastguard Worker }
325*35238bceSAndroid Build Coastguard Worker 
write(uint32_t buffer,int offset,int numBytes,const uint8_t * bytes,uint32_t targetHint)326*35238bceSAndroid Build Coastguard Worker void BufferWriter::write(uint32_t buffer, int offset, int numBytes, const uint8_t *bytes, uint32_t targetHint)
327*35238bceSAndroid Build Coastguard Worker {
328*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numBytes >= getMinSize());
329*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(offset % getAlignment() == 0);
330*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((offset + numBytes) % getAlignment() == 0);
331*35238bceSAndroid Build Coastguard Worker     return m_writer->write(buffer, offset, numBytes, bytes, targetHint);
332*35238bceSAndroid Build Coastguard Worker }
333*35238bceSAndroid Build Coastguard Worker 
334*35238bceSAndroid Build Coastguard Worker // BufferSubDataWriter
335*35238bceSAndroid Build Coastguard Worker 
write(uint32_t buffer,int offset,int numBytes,const uint8_t * bytes)336*35238bceSAndroid Build Coastguard Worker void BufferSubDataWriter::write(uint32_t buffer, int offset, int numBytes, const uint8_t *bytes)
337*35238bceSAndroid Build Coastguard Worker {
338*35238bceSAndroid Build Coastguard Worker     write(buffer, offset, numBytes, bytes, GL_ARRAY_BUFFER);
339*35238bceSAndroid Build Coastguard Worker }
340*35238bceSAndroid Build Coastguard Worker 
write(uint32_t buffer,int offset,int numBytes,const uint8_t * bytes,uint32_t target)341*35238bceSAndroid Build Coastguard Worker void BufferSubDataWriter::write(uint32_t buffer, int offset, int numBytes, const uint8_t *bytes, uint32_t target)
342*35238bceSAndroid Build Coastguard Worker {
343*35238bceSAndroid Build Coastguard Worker     glBindBuffer(target, buffer);
344*35238bceSAndroid Build Coastguard Worker     glBufferSubData(target, offset, numBytes, bytes);
345*35238bceSAndroid Build Coastguard Worker     glBindBuffer(target, 0);
346*35238bceSAndroid Build Coastguard Worker     GLU_CHECK();
347*35238bceSAndroid Build Coastguard Worker }
348*35238bceSAndroid Build Coastguard Worker 
349*35238bceSAndroid Build Coastguard Worker // BufferWriteMapWriter
350*35238bceSAndroid Build Coastguard Worker 
write(uint32_t buffer,int offset,int numBytes,const uint8_t * bytes)351*35238bceSAndroid Build Coastguard Worker void BufferWriteMapWriter::write(uint32_t buffer, int offset, int numBytes, const uint8_t *bytes)
352*35238bceSAndroid Build Coastguard Worker {
353*35238bceSAndroid Build Coastguard Worker     write(buffer, offset, numBytes, bytes, GL_ARRAY_BUFFER);
354*35238bceSAndroid Build Coastguard Worker }
355*35238bceSAndroid Build Coastguard Worker 
write(uint32_t buffer,int offset,int numBytes,const uint8_t * bytes,uint32_t target)356*35238bceSAndroid Build Coastguard Worker void BufferWriteMapWriter::write(uint32_t buffer, int offset, int numBytes, const uint8_t *bytes, uint32_t target)
357*35238bceSAndroid Build Coastguard Worker {
358*35238bceSAndroid Build Coastguard Worker     glBindBuffer(target, buffer);
359*35238bceSAndroid Build Coastguard Worker 
360*35238bceSAndroid Build Coastguard Worker     void *ptr = glMapBufferRange(target, offset, numBytes, GL_MAP_WRITE_BIT);
361*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_MSG("glMapBufferRange");
362*35238bceSAndroid Build Coastguard Worker 
363*35238bceSAndroid Build Coastguard Worker     deMemcpy(ptr, bytes, numBytes);
364*35238bceSAndroid Build Coastguard Worker 
365*35238bceSAndroid Build Coastguard Worker     glUnmapBuffer(target);
366*35238bceSAndroid Build Coastguard Worker     glBindBuffer(target, 0);
367*35238bceSAndroid Build Coastguard Worker     GLU_CHECK();
368*35238bceSAndroid Build Coastguard Worker }
369*35238bceSAndroid Build Coastguard Worker 
370*35238bceSAndroid Build Coastguard Worker // BufferVerifierBase
371*35238bceSAndroid Build Coastguard Worker 
BufferVerifierBase(glu::RenderContext & renderCtx,tcu::TestLog & log)372*35238bceSAndroid Build Coastguard Worker BufferVerifierBase::BufferVerifierBase(glu::RenderContext &renderCtx, tcu::TestLog &log)
373*35238bceSAndroid Build Coastguard Worker     : CallLogWrapper(renderCtx.getFunctions(), log)
374*35238bceSAndroid Build Coastguard Worker     , m_renderCtx(renderCtx)
375*35238bceSAndroid Build Coastguard Worker     , m_log(log)
376*35238bceSAndroid Build Coastguard Worker {
377*35238bceSAndroid Build Coastguard Worker     enableLogging(true);
378*35238bceSAndroid Build Coastguard Worker }
379*35238bceSAndroid Build Coastguard Worker 
verify(uint32_t buffer,const uint8_t * reference,int offset,int numBytes,uint32_t targetHint)380*35238bceSAndroid Build Coastguard Worker bool BufferVerifierBase::verify(uint32_t buffer, const uint8_t *reference, int offset, int numBytes,
381*35238bceSAndroid Build Coastguard Worker                                 uint32_t targetHint)
382*35238bceSAndroid Build Coastguard Worker {
383*35238bceSAndroid Build Coastguard Worker     DE_UNREF(targetHint);
384*35238bceSAndroid Build Coastguard Worker     return verify(buffer, reference, offset, numBytes);
385*35238bceSAndroid Build Coastguard Worker }
386*35238bceSAndroid Build Coastguard Worker 
387*35238bceSAndroid Build Coastguard Worker // BufferVerifier
388*35238bceSAndroid Build Coastguard Worker 
BufferVerifier(glu::RenderContext & renderCtx,tcu::TestLog & log,VerifyType verifyType)389*35238bceSAndroid Build Coastguard Worker BufferVerifier::BufferVerifier(glu::RenderContext &renderCtx, tcu::TestLog &log, VerifyType verifyType)
390*35238bceSAndroid Build Coastguard Worker     : m_verifier(DE_NULL)
391*35238bceSAndroid Build Coastguard Worker {
392*35238bceSAndroid Build Coastguard Worker     switch (verifyType)
393*35238bceSAndroid Build Coastguard Worker     {
394*35238bceSAndroid Build Coastguard Worker     case VERIFY_AS_VERTEX_ARRAY:
395*35238bceSAndroid Build Coastguard Worker         m_verifier = new VertexArrayVerifier(renderCtx, log);
396*35238bceSAndroid Build Coastguard Worker         break;
397*35238bceSAndroid Build Coastguard Worker     case VERIFY_AS_INDEX_ARRAY:
398*35238bceSAndroid Build Coastguard Worker         m_verifier = new IndexArrayVerifier(renderCtx, log);
399*35238bceSAndroid Build Coastguard Worker         break;
400*35238bceSAndroid Build Coastguard Worker     case VERIFY_BUFFER_READ_MAP:
401*35238bceSAndroid Build Coastguard Worker         m_verifier = new BufferMapVerifier(renderCtx, log);
402*35238bceSAndroid Build Coastguard Worker         break;
403*35238bceSAndroid Build Coastguard Worker     default:
404*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Unsupported verifier");
405*35238bceSAndroid Build Coastguard Worker     }
406*35238bceSAndroid Build Coastguard Worker }
407*35238bceSAndroid Build Coastguard Worker 
~BufferVerifier(void)408*35238bceSAndroid Build Coastguard Worker BufferVerifier::~BufferVerifier(void)
409*35238bceSAndroid Build Coastguard Worker {
410*35238bceSAndroid Build Coastguard Worker     delete m_verifier;
411*35238bceSAndroid Build Coastguard Worker }
412*35238bceSAndroid Build Coastguard Worker 
verify(uint32_t buffer,const uint8_t * reference,int offset,int numBytes)413*35238bceSAndroid Build Coastguard Worker bool BufferVerifier::verify(uint32_t buffer, const uint8_t *reference, int offset, int numBytes)
414*35238bceSAndroid Build Coastguard Worker {
415*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numBytes >= getMinSize());
416*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(offset % getAlignment() == 0);
417*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((offset + numBytes) % getAlignment() == 0);
418*35238bceSAndroid Build Coastguard Worker     return m_verifier->verify(buffer, reference, offset, numBytes);
419*35238bceSAndroid Build Coastguard Worker }
420*35238bceSAndroid Build Coastguard Worker 
verify(uint32_t buffer,const uint8_t * reference,int offset,int numBytes,uint32_t targetHint)421*35238bceSAndroid Build Coastguard Worker bool BufferVerifier::verify(uint32_t buffer, const uint8_t *reference, int offset, int numBytes, uint32_t targetHint)
422*35238bceSAndroid Build Coastguard Worker {
423*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numBytes >= getMinSize());
424*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(offset % getAlignment() == 0);
425*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((offset + numBytes) % getAlignment() == 0);
426*35238bceSAndroid Build Coastguard Worker     return m_verifier->verify(buffer, reference, offset, numBytes, targetHint);
427*35238bceSAndroid Build Coastguard Worker }
428*35238bceSAndroid Build Coastguard Worker 
429*35238bceSAndroid Build Coastguard Worker // BufferMapVerifier
430*35238bceSAndroid Build Coastguard Worker 
verify(uint32_t buffer,const uint8_t * reference,int offset,int numBytes)431*35238bceSAndroid Build Coastguard Worker bool BufferMapVerifier::verify(uint32_t buffer, const uint8_t *reference, int offset, int numBytes)
432*35238bceSAndroid Build Coastguard Worker {
433*35238bceSAndroid Build Coastguard Worker     return verify(buffer, reference, offset, numBytes, GL_ARRAY_BUFFER);
434*35238bceSAndroid Build Coastguard Worker }
435*35238bceSAndroid Build Coastguard Worker 
verify(uint32_t buffer,const uint8_t * reference,int offset,int numBytes,uint32_t target)436*35238bceSAndroid Build Coastguard Worker bool BufferMapVerifier::verify(uint32_t buffer, const uint8_t *reference, int offset, int numBytes, uint32_t target)
437*35238bceSAndroid Build Coastguard Worker {
438*35238bceSAndroid Build Coastguard Worker     const uint8_t *mapPtr = DE_NULL;
439*35238bceSAndroid Build Coastguard Worker     bool isOk             = false;
440*35238bceSAndroid Build Coastguard Worker 
441*35238bceSAndroid Build Coastguard Worker     glBindBuffer(target, buffer);
442*35238bceSAndroid Build Coastguard Worker     mapPtr = (const uint8_t *)glMapBufferRange(target, offset, numBytes, GL_MAP_READ_BIT);
443*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_MSG("glMapBufferRange");
444*35238bceSAndroid Build Coastguard Worker     TCU_CHECK(mapPtr);
445*35238bceSAndroid Build Coastguard Worker 
446*35238bceSAndroid Build Coastguard Worker     isOk = compareByteArrays(m_log, mapPtr, reference + offset, numBytes);
447*35238bceSAndroid Build Coastguard Worker 
448*35238bceSAndroid Build Coastguard Worker     glUnmapBuffer(target);
449*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_MSG("glUnmapBuffer");
450*35238bceSAndroid Build Coastguard Worker 
451*35238bceSAndroid Build Coastguard Worker     glBindBuffer(target, 0);
452*35238bceSAndroid Build Coastguard Worker 
453*35238bceSAndroid Build Coastguard Worker     return isOk;
454*35238bceSAndroid Build Coastguard Worker }
455*35238bceSAndroid Build Coastguard Worker 
456*35238bceSAndroid Build Coastguard Worker // VertexArrayVerifier
457*35238bceSAndroid Build Coastguard Worker 
VertexArrayVerifier(glu::RenderContext & renderCtx,tcu::TestLog & log)458*35238bceSAndroid Build Coastguard Worker VertexArrayVerifier::VertexArrayVerifier(glu::RenderContext &renderCtx, tcu::TestLog &log)
459*35238bceSAndroid Build Coastguard Worker     : BufferVerifierBase(renderCtx, log)
460*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
461*35238bceSAndroid Build Coastguard Worker     , m_posLoc(0)
462*35238bceSAndroid Build Coastguard Worker     , m_byteVecLoc(0)
463*35238bceSAndroid Build Coastguard Worker     , m_vao(0)
464*35238bceSAndroid Build Coastguard Worker {
465*35238bceSAndroid Build Coastguard Worker     const glu::ContextType ctxType = renderCtx.getType();
466*35238bceSAndroid Build Coastguard Worker     const glu::GLSLVersion glslVersion =
467*35238bceSAndroid Build Coastguard Worker         glu::isContextTypeES(ctxType) ? glu::GLSL_VERSION_300_ES : glu::GLSL_VERSION_330;
468*35238bceSAndroid Build Coastguard Worker 
469*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(glu::isGLSLVersionSupported(ctxType, glslVersion));
470*35238bceSAndroid Build Coastguard Worker 
471*35238bceSAndroid Build Coastguard Worker     m_program = new glu::ShaderProgram(m_renderCtx,
472*35238bceSAndroid Build Coastguard Worker                                        glu::makeVtxFragSources(string(glu::getGLSLVersionDeclaration(glslVersion)) +
473*35238bceSAndroid Build Coastguard Worker                                                                    "\n"
474*35238bceSAndroid Build Coastguard Worker                                                                    "in highp vec2 a_position;\n"
475*35238bceSAndroid Build Coastguard Worker                                                                    "in mediump vec3 a_byteVec;\n"
476*35238bceSAndroid Build Coastguard Worker                                                                    "out mediump vec3 v_byteVec;\n"
477*35238bceSAndroid Build Coastguard Worker                                                                    "void main (void)\n"
478*35238bceSAndroid Build Coastguard Worker                                                                    "{\n"
479*35238bceSAndroid Build Coastguard Worker                                                                    "    gl_Position = vec4(a_position, 0.0, 1.0);\n"
480*35238bceSAndroid Build Coastguard Worker                                                                    "    v_byteVec = a_byteVec;\n"
481*35238bceSAndroid Build Coastguard Worker                                                                    "}\n",
482*35238bceSAndroid Build Coastguard Worker 
483*35238bceSAndroid Build Coastguard Worker                                                                string(glu::getGLSLVersionDeclaration(glslVersion)) +
484*35238bceSAndroid Build Coastguard Worker                                                                    "\n"
485*35238bceSAndroid Build Coastguard Worker                                                                    "in mediump vec3 v_byteVec;\n"
486*35238bceSAndroid Build Coastguard Worker                                                                    "layout(location = 0) out mediump vec4 o_color;\n"
487*35238bceSAndroid Build Coastguard Worker                                                                    "void main (void)\n"
488*35238bceSAndroid Build Coastguard Worker                                                                    "{\n"
489*35238bceSAndroid Build Coastguard Worker                                                                    "    o_color = vec4(v_byteVec, 1.0);\n"
490*35238bceSAndroid Build Coastguard Worker                                                                    "}\n"));
491*35238bceSAndroid Build Coastguard Worker 
492*35238bceSAndroid Build Coastguard Worker     if (!m_program->isOk())
493*35238bceSAndroid Build Coastguard Worker     {
494*35238bceSAndroid Build Coastguard Worker         m_log << *m_program;
495*35238bceSAndroid Build Coastguard Worker         delete m_program;
496*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Compile failed");
497*35238bceSAndroid Build Coastguard Worker     }
498*35238bceSAndroid Build Coastguard Worker 
499*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_renderCtx.getFunctions();
500*35238bceSAndroid Build Coastguard Worker     m_posLoc                 = gl.getAttribLocation(m_program->getProgram(), "a_position");
501*35238bceSAndroid Build Coastguard Worker     m_byteVecLoc             = gl.getAttribLocation(m_program->getProgram(), "a_byteVec");
502*35238bceSAndroid Build Coastguard Worker 
503*35238bceSAndroid Build Coastguard Worker     gl.genVertexArrays(1, &m_vao);
504*35238bceSAndroid Build Coastguard Worker     gl.genBuffers(1, &m_positionBuf);
505*35238bceSAndroid Build Coastguard Worker     gl.genBuffers(1, &m_indexBuf);
506*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "Initialization failed");
507*35238bceSAndroid Build Coastguard Worker }
508*35238bceSAndroid Build Coastguard Worker 
~VertexArrayVerifier(void)509*35238bceSAndroid Build Coastguard Worker VertexArrayVerifier::~VertexArrayVerifier(void)
510*35238bceSAndroid Build Coastguard Worker {
511*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_renderCtx.getFunctions();
512*35238bceSAndroid Build Coastguard Worker 
513*35238bceSAndroid Build Coastguard Worker     if (m_vao)
514*35238bceSAndroid Build Coastguard Worker         gl.deleteVertexArrays(1, &m_vao);
515*35238bceSAndroid Build Coastguard Worker     if (m_positionBuf)
516*35238bceSAndroid Build Coastguard Worker         gl.deleteBuffers(1, &m_positionBuf);
517*35238bceSAndroid Build Coastguard Worker     if (m_indexBuf)
518*35238bceSAndroid Build Coastguard Worker         gl.deleteBuffers(1, &m_indexBuf);
519*35238bceSAndroid Build Coastguard Worker 
520*35238bceSAndroid Build Coastguard Worker     delete m_program;
521*35238bceSAndroid Build Coastguard Worker }
522*35238bceSAndroid Build Coastguard Worker 
computePositions(vector<tcu::Vec2> & positions,int gridSizeX,int gridSizeY)523*35238bceSAndroid Build Coastguard Worker static void computePositions(vector<tcu::Vec2> &positions, int gridSizeX, int gridSizeY)
524*35238bceSAndroid Build Coastguard Worker {
525*35238bceSAndroid Build Coastguard Worker     positions.resize(gridSizeX * gridSizeY * 4);
526*35238bceSAndroid Build Coastguard Worker 
527*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < gridSizeY; y++)
528*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < gridSizeX; x++)
529*35238bceSAndroid Build Coastguard Worker         {
530*35238bceSAndroid Build Coastguard Worker             float sx0   = (float)(x + 0) / (float)gridSizeX;
531*35238bceSAndroid Build Coastguard Worker             float sy0   = (float)(y + 0) / (float)gridSizeY;
532*35238bceSAndroid Build Coastguard Worker             float sx1   = (float)(x + 1) / (float)gridSizeX;
533*35238bceSAndroid Build Coastguard Worker             float sy1   = (float)(y + 1) / (float)gridSizeY;
534*35238bceSAndroid Build Coastguard Worker             float fx0   = 2.0f * sx0 - 1.0f;
535*35238bceSAndroid Build Coastguard Worker             float fy0   = 2.0f * sy0 - 1.0f;
536*35238bceSAndroid Build Coastguard Worker             float fx1   = 2.0f * sx1 - 1.0f;
537*35238bceSAndroid Build Coastguard Worker             float fy1   = 2.0f * sy1 - 1.0f;
538*35238bceSAndroid Build Coastguard Worker             int baseNdx = (y * gridSizeX + x) * 4;
539*35238bceSAndroid Build Coastguard Worker 
540*35238bceSAndroid Build Coastguard Worker             positions[baseNdx + 0] = tcu::Vec2(fx0, fy0);
541*35238bceSAndroid Build Coastguard Worker             positions[baseNdx + 1] = tcu::Vec2(fx0, fy1);
542*35238bceSAndroid Build Coastguard Worker             positions[baseNdx + 2] = tcu::Vec2(fx1, fy0);
543*35238bceSAndroid Build Coastguard Worker             positions[baseNdx + 3] = tcu::Vec2(fx1, fy1);
544*35238bceSAndroid Build Coastguard Worker         }
545*35238bceSAndroid Build Coastguard Worker }
546*35238bceSAndroid Build Coastguard Worker 
computeIndices(vector<uint16_t> & indices,int gridSizeX,int gridSizeY)547*35238bceSAndroid Build Coastguard Worker static void computeIndices(vector<uint16_t> &indices, int gridSizeX, int gridSizeY)
548*35238bceSAndroid Build Coastguard Worker {
549*35238bceSAndroid Build Coastguard Worker     indices.resize(3 * 2 * gridSizeX * gridSizeY);
550*35238bceSAndroid Build Coastguard Worker 
551*35238bceSAndroid Build Coastguard Worker     for (int quadNdx = 0; quadNdx < gridSizeX * gridSizeY; quadNdx++)
552*35238bceSAndroid Build Coastguard Worker     {
553*35238bceSAndroid Build Coastguard Worker         int v00 = quadNdx * 4 + 0;
554*35238bceSAndroid Build Coastguard Worker         int v01 = quadNdx * 4 + 1;
555*35238bceSAndroid Build Coastguard Worker         int v10 = quadNdx * 4 + 2;
556*35238bceSAndroid Build Coastguard Worker         int v11 = quadNdx * 4 + 3;
557*35238bceSAndroid Build Coastguard Worker 
558*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(v11 < (1 << 16));
559*35238bceSAndroid Build Coastguard Worker 
560*35238bceSAndroid Build Coastguard Worker         indices[quadNdx * 6 + 0] = (uint16_t)v10;
561*35238bceSAndroid Build Coastguard Worker         indices[quadNdx * 6 + 1] = (uint16_t)v00;
562*35238bceSAndroid Build Coastguard Worker         indices[quadNdx * 6 + 2] = (uint16_t)v01;
563*35238bceSAndroid Build Coastguard Worker 
564*35238bceSAndroid Build Coastguard Worker         indices[quadNdx * 6 + 3] = (uint16_t)v10;
565*35238bceSAndroid Build Coastguard Worker         indices[quadNdx * 6 + 4] = (uint16_t)v01;
566*35238bceSAndroid Build Coastguard Worker         indices[quadNdx * 6 + 5] = (uint16_t)v11;
567*35238bceSAndroid Build Coastguard Worker     }
568*35238bceSAndroid Build Coastguard Worker }
569*35238bceSAndroid Build Coastguard Worker 
fetchVtxColor(const uint8_t * ptr,int vtxNdx)570*35238bceSAndroid Build Coastguard Worker static inline tcu::Vec4 fetchVtxColor(const uint8_t *ptr, int vtxNdx)
571*35238bceSAndroid Build Coastguard Worker {
572*35238bceSAndroid Build Coastguard Worker     return tcu::RGBA(*(ptr + vtxNdx * 3 + 0), *(ptr + vtxNdx * 3 + 1), *(ptr + vtxNdx * 3 + 2), 255).toVec();
573*35238bceSAndroid Build Coastguard Worker }
574*35238bceSAndroid Build Coastguard Worker 
renderQuadGridReference(tcu::Surface & dst,int numQuads,int rowLength,const uint8_t * inPtr)575*35238bceSAndroid Build Coastguard Worker static void renderQuadGridReference(tcu::Surface &dst, int numQuads, int rowLength, const uint8_t *inPtr)
576*35238bceSAndroid Build Coastguard Worker {
577*35238bceSAndroid Build Coastguard Worker     using tcu::Vec4;
578*35238bceSAndroid Build Coastguard Worker 
579*35238bceSAndroid Build Coastguard Worker     dst.setSize(rowLength * VERIFY_QUAD_SIZE,
580*35238bceSAndroid Build Coastguard Worker                 (numQuads / rowLength + (numQuads % rowLength != 0 ? 1 : 0)) * VERIFY_QUAD_SIZE);
581*35238bceSAndroid Build Coastguard Worker 
582*35238bceSAndroid Build Coastguard Worker     tcu::PixelBufferAccess dstAccess = dst.getAccess();
583*35238bceSAndroid Build Coastguard Worker     tcu::clear(dstAccess, tcu::IVec4(0, 0, 0, 0xff));
584*35238bceSAndroid Build Coastguard Worker 
585*35238bceSAndroid Build Coastguard Worker     for (int quadNdx = 0; quadNdx < numQuads; quadNdx++)
586*35238bceSAndroid Build Coastguard Worker     {
587*35238bceSAndroid Build Coastguard Worker         int x0   = (quadNdx % rowLength) * VERIFY_QUAD_SIZE;
588*35238bceSAndroid Build Coastguard Worker         int y0   = (quadNdx / rowLength) * VERIFY_QUAD_SIZE;
589*35238bceSAndroid Build Coastguard Worker         Vec4 v00 = fetchVtxColor(inPtr, quadNdx * 4 + 0);
590*35238bceSAndroid Build Coastguard Worker         Vec4 v10 = fetchVtxColor(inPtr, quadNdx * 4 + 1);
591*35238bceSAndroid Build Coastguard Worker         Vec4 v01 = fetchVtxColor(inPtr, quadNdx * 4 + 2);
592*35238bceSAndroid Build Coastguard Worker         Vec4 v11 = fetchVtxColor(inPtr, quadNdx * 4 + 3);
593*35238bceSAndroid Build Coastguard Worker 
594*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < VERIFY_QUAD_SIZE; y++)
595*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < VERIFY_QUAD_SIZE; x++)
596*35238bceSAndroid Build Coastguard Worker             {
597*35238bceSAndroid Build Coastguard Worker                 float fx = ((float)x + 0.5f) / (float)VERIFY_QUAD_SIZE;
598*35238bceSAndroid Build Coastguard Worker                 float fy = ((float)y + 0.5f) / (float)VERIFY_QUAD_SIZE;
599*35238bceSAndroid Build Coastguard Worker 
600*35238bceSAndroid Build Coastguard Worker                 bool tri       = fx + fy <= 1.0f;
601*35238bceSAndroid Build Coastguard Worker                 float tx       = tri ? fx : (1.0f - fx);
602*35238bceSAndroid Build Coastguard Worker                 float ty       = tri ? fy : (1.0f - fy);
603*35238bceSAndroid Build Coastguard Worker                 const Vec4 &t0 = tri ? v00 : v11;
604*35238bceSAndroid Build Coastguard Worker                 const Vec4 &t1 = tri ? v01 : v10;
605*35238bceSAndroid Build Coastguard Worker                 const Vec4 &t2 = tri ? v10 : v01;
606*35238bceSAndroid Build Coastguard Worker                 Vec4 color     = t0 + (t1 - t0) * tx + (t2 - t0) * ty;
607*35238bceSAndroid Build Coastguard Worker 
608*35238bceSAndroid Build Coastguard Worker                 dstAccess.setPixel(color, x0 + x, y0 + y);
609*35238bceSAndroid Build Coastguard Worker             }
610*35238bceSAndroid Build Coastguard Worker     }
611*35238bceSAndroid Build Coastguard Worker }
612*35238bceSAndroid Build Coastguard Worker 
verify(uint32_t buffer,const uint8_t * refPtr,int offset,int numBytes)613*35238bceSAndroid Build Coastguard Worker bool VertexArrayVerifier::verify(uint32_t buffer, const uint8_t *refPtr, int offset, int numBytes)
614*35238bceSAndroid Build Coastguard Worker {
615*35238bceSAndroid Build Coastguard Worker     const tcu::RenderTarget &renderTarget = m_renderCtx.getRenderTarget();
616*35238bceSAndroid Build Coastguard Worker     const int numBytesInVtx               = 3;
617*35238bceSAndroid Build Coastguard Worker     const int numBytesInQuad              = numBytesInVtx * 4;
618*35238bceSAndroid Build Coastguard Worker     int maxQuadsX                         = de::min(128, renderTarget.getWidth() / VERIFY_QUAD_SIZE);
619*35238bceSAndroid Build Coastguard Worker     int maxQuadsY                         = de::min(128, renderTarget.getHeight() / VERIFY_QUAD_SIZE);
620*35238bceSAndroid Build Coastguard Worker     int maxQuadsPerBatch                  = maxQuadsX * maxQuadsY;
621*35238bceSAndroid Build Coastguard Worker     int numVerified                       = 0;
622*35238bceSAndroid Build Coastguard Worker     uint32_t program                      = m_program->getProgram();
623*35238bceSAndroid Build Coastguard Worker     tcu::RGBA threshold                   = renderTarget.getPixelFormat().getColorThreshold() + tcu::RGBA(3, 3, 3, 3);
624*35238bceSAndroid Build Coastguard Worker     bool isOk                             = true;
625*35238bceSAndroid Build Coastguard Worker 
626*35238bceSAndroid Build Coastguard Worker     vector<tcu::Vec2> positions;
627*35238bceSAndroid Build Coastguard Worker     vector<uint16_t> indices;
628*35238bceSAndroid Build Coastguard Worker 
629*35238bceSAndroid Build Coastguard Worker     tcu::Surface rendered;
630*35238bceSAndroid Build Coastguard Worker     tcu::Surface reference;
631*35238bceSAndroid Build Coastguard Worker 
632*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numBytes >= numBytesInQuad); // Can't render full quad with smaller buffers.
633*35238bceSAndroid Build Coastguard Worker 
634*35238bceSAndroid Build Coastguard Worker     computePositions(positions, maxQuadsX, maxQuadsY);
635*35238bceSAndroid Build Coastguard Worker     computeIndices(indices, maxQuadsX, maxQuadsY);
636*35238bceSAndroid Build Coastguard Worker 
637*35238bceSAndroid Build Coastguard Worker     // Reset buffer bindings.
638*35238bceSAndroid Build Coastguard Worker     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
639*35238bceSAndroid Build Coastguard Worker 
640*35238bceSAndroid Build Coastguard Worker     // Setup rendering state.
641*35238bceSAndroid Build Coastguard Worker     glViewport(0, 0, maxQuadsX * VERIFY_QUAD_SIZE, maxQuadsY * VERIFY_QUAD_SIZE);
642*35238bceSAndroid Build Coastguard Worker     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
643*35238bceSAndroid Build Coastguard Worker     glUseProgram(program);
644*35238bceSAndroid Build Coastguard Worker     glBindVertexArray(m_vao);
645*35238bceSAndroid Build Coastguard Worker 
646*35238bceSAndroid Build Coastguard Worker     // Upload positions
647*35238bceSAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, m_positionBuf);
648*35238bceSAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(positions.size() * sizeof(positions[0])), &positions[0],
649*35238bceSAndroid Build Coastguard Worker                  GL_STATIC_DRAW);
650*35238bceSAndroid Build Coastguard Worker     glEnableVertexAttribArray(m_posLoc);
651*35238bceSAndroid Build Coastguard Worker     glVertexAttribPointer(m_posLoc, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL);
652*35238bceSAndroid Build Coastguard Worker 
653*35238bceSAndroid Build Coastguard Worker     // Upload indices
654*35238bceSAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuf);
655*35238bceSAndroid Build Coastguard Worker     glBufferData(GL_ELEMENT_ARRAY_BUFFER, (glw::GLsizeiptr)(indices.size() * sizeof(indices[0])), &indices[0],
656*35238bceSAndroid Build Coastguard Worker                  GL_STATIC_DRAW);
657*35238bceSAndroid Build Coastguard Worker 
658*35238bceSAndroid Build Coastguard Worker     glEnableVertexAttribArray(m_byteVecLoc);
659*35238bceSAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, buffer);
660*35238bceSAndroid Build Coastguard Worker 
661*35238bceSAndroid Build Coastguard Worker     while (numVerified < numBytes)
662*35238bceSAndroid Build Coastguard Worker     {
663*35238bceSAndroid Build Coastguard Worker         int numRemaining     = numBytes - numVerified;
664*35238bceSAndroid Build Coastguard Worker         bool isLeftoverBatch = numRemaining < numBytesInQuad;
665*35238bceSAndroid Build Coastguard Worker         int numBytesToVerify =
666*35238bceSAndroid Build Coastguard Worker             isLeftoverBatch ? numBytesInQuad :
667*35238bceSAndroid Build Coastguard Worker                               de::min(maxQuadsPerBatch * numBytesInQuad, numRemaining - numRemaining % numBytesInQuad);
668*35238bceSAndroid Build Coastguard Worker         int curOffset       = isLeftoverBatch ? (numBytes - numBytesInQuad) : numVerified;
669*35238bceSAndroid Build Coastguard Worker         int numQuads        = numBytesToVerify / numBytesInQuad;
670*35238bceSAndroid Build Coastguard Worker         int numCols         = de::min(maxQuadsX, numQuads);
671*35238bceSAndroid Build Coastguard Worker         int numRows         = numQuads / maxQuadsX + (numQuads % maxQuadsX != 0 ? 1 : 0);
672*35238bceSAndroid Build Coastguard Worker         string imageSetDesc = string("Bytes ") + de::toString(offset + curOffset) + " to " +
673*35238bceSAndroid Build Coastguard Worker                               de::toString(offset + curOffset + numBytesToVerify - 1);
674*35238bceSAndroid Build Coastguard Worker 
675*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(numBytesToVerify > 0 && numBytesToVerify % numBytesInQuad == 0);
676*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(de::inBounds(curOffset, 0, numBytes));
677*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(de::inRange(curOffset + numBytesToVerify, curOffset, numBytes));
678*35238bceSAndroid Build Coastguard Worker 
679*35238bceSAndroid Build Coastguard Worker         // Render batch.
680*35238bceSAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
681*35238bceSAndroid Build Coastguard Worker         glVertexAttribPointer(m_byteVecLoc, 3, GL_UNSIGNED_BYTE, GL_TRUE, 0,
682*35238bceSAndroid Build Coastguard Worker                               (const glw::GLvoid *)(uintptr_t)(offset + curOffset));
683*35238bceSAndroid Build Coastguard Worker         glDrawElements(GL_TRIANGLES, numQuads * 6, GL_UNSIGNED_SHORT, DE_NULL);
684*35238bceSAndroid Build Coastguard Worker 
685*35238bceSAndroid Build Coastguard Worker         renderQuadGridReference(reference, numQuads, numCols, refPtr + offset + curOffset);
686*35238bceSAndroid Build Coastguard Worker 
687*35238bceSAndroid Build Coastguard Worker         rendered.setSize(numCols * VERIFY_QUAD_SIZE, numRows * VERIFY_QUAD_SIZE);
688*35238bceSAndroid Build Coastguard Worker         glu::readPixels(m_renderCtx, 0, 0, rendered.getAccess());
689*35238bceSAndroid Build Coastguard Worker 
690*35238bceSAndroid Build Coastguard Worker         if (!tcu::pixelThresholdCompare(m_log, "RenderResult", imageSetDesc.c_str(), reference, rendered, threshold,
691*35238bceSAndroid Build Coastguard Worker                                         tcu::COMPARE_LOG_RESULT))
692*35238bceSAndroid Build Coastguard Worker         {
693*35238bceSAndroid Build Coastguard Worker             isOk = false;
694*35238bceSAndroid Build Coastguard Worker             break;
695*35238bceSAndroid Build Coastguard Worker         }
696*35238bceSAndroid Build Coastguard Worker 
697*35238bceSAndroid Build Coastguard Worker         numVerified += isLeftoverBatch ? numRemaining : numBytesToVerify;
698*35238bceSAndroid Build Coastguard Worker     }
699*35238bceSAndroid Build Coastguard Worker 
700*35238bceSAndroid Build Coastguard Worker     glBindVertexArray(0);
701*35238bceSAndroid Build Coastguard Worker 
702*35238bceSAndroid Build Coastguard Worker     return isOk;
703*35238bceSAndroid Build Coastguard Worker }
704*35238bceSAndroid Build Coastguard Worker 
705*35238bceSAndroid Build Coastguard Worker // IndexArrayVerifier
706*35238bceSAndroid Build Coastguard Worker 
IndexArrayVerifier(glu::RenderContext & renderCtx,tcu::TestLog & log)707*35238bceSAndroid Build Coastguard Worker IndexArrayVerifier::IndexArrayVerifier(glu::RenderContext &renderCtx, tcu::TestLog &log)
708*35238bceSAndroid Build Coastguard Worker     : BufferVerifierBase(renderCtx, log)
709*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
710*35238bceSAndroid Build Coastguard Worker     , m_posLoc(0)
711*35238bceSAndroid Build Coastguard Worker     , m_colorLoc(0)
712*35238bceSAndroid Build Coastguard Worker {
713*35238bceSAndroid Build Coastguard Worker 
714*35238bceSAndroid Build Coastguard Worker     const glu::ContextType ctxType = renderCtx.getType();
715*35238bceSAndroid Build Coastguard Worker     const glu::GLSLVersion glslVersion =
716*35238bceSAndroid Build Coastguard Worker         glu::isContextTypeES(ctxType) ? glu::GLSL_VERSION_300_ES : glu::GLSL_VERSION_330;
717*35238bceSAndroid Build Coastguard Worker 
718*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(glu::isGLSLVersionSupported(ctxType, glslVersion));
719*35238bceSAndroid Build Coastguard Worker 
720*35238bceSAndroid Build Coastguard Worker     m_program = new glu::ShaderProgram(m_renderCtx,
721*35238bceSAndroid Build Coastguard Worker                                        glu::makeVtxFragSources(string(glu::getGLSLVersionDeclaration(glslVersion)) +
722*35238bceSAndroid Build Coastguard Worker                                                                    "\n"
723*35238bceSAndroid Build Coastguard Worker                                                                    "in highp vec2 a_position;\n"
724*35238bceSAndroid Build Coastguard Worker                                                                    "in mediump vec3 a_color;\n"
725*35238bceSAndroid Build Coastguard Worker                                                                    "out mediump vec3 v_color;\n"
726*35238bceSAndroid Build Coastguard Worker                                                                    "void main (void)\n"
727*35238bceSAndroid Build Coastguard Worker                                                                    "{\n"
728*35238bceSAndroid Build Coastguard Worker                                                                    "    gl_Position = vec4(a_position, 0.0, 1.0);\n"
729*35238bceSAndroid Build Coastguard Worker                                                                    "    v_color = a_color;\n"
730*35238bceSAndroid Build Coastguard Worker                                                                    "}\n",
731*35238bceSAndroid Build Coastguard Worker 
732*35238bceSAndroid Build Coastguard Worker                                                                string(glu::getGLSLVersionDeclaration(glslVersion)) +
733*35238bceSAndroid Build Coastguard Worker                                                                    "\n"
734*35238bceSAndroid Build Coastguard Worker                                                                    "in mediump vec3 v_color;\n"
735*35238bceSAndroid Build Coastguard Worker                                                                    "layout(location = 0) out mediump vec4 o_color;\n"
736*35238bceSAndroid Build Coastguard Worker                                                                    "void main (void)\n"
737*35238bceSAndroid Build Coastguard Worker                                                                    "{\n"
738*35238bceSAndroid Build Coastguard Worker                                                                    "    o_color = vec4(v_color, 1.0);\n"
739*35238bceSAndroid Build Coastguard Worker                                                                    "}\n"));
740*35238bceSAndroid Build Coastguard Worker 
741*35238bceSAndroid Build Coastguard Worker     if (!m_program->isOk())
742*35238bceSAndroid Build Coastguard Worker     {
743*35238bceSAndroid Build Coastguard Worker         m_log << *m_program;
744*35238bceSAndroid Build Coastguard Worker         delete m_program;
745*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Compile failed");
746*35238bceSAndroid Build Coastguard Worker     }
747*35238bceSAndroid Build Coastguard Worker 
748*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_renderCtx.getFunctions();
749*35238bceSAndroid Build Coastguard Worker     m_posLoc                 = gl.getAttribLocation(m_program->getProgram(), "a_position");
750*35238bceSAndroid Build Coastguard Worker     m_colorLoc               = gl.getAttribLocation(m_program->getProgram(), "a_color");
751*35238bceSAndroid Build Coastguard Worker 
752*35238bceSAndroid Build Coastguard Worker     gl.genVertexArrays(1, &m_vao);
753*35238bceSAndroid Build Coastguard Worker     gl.genBuffers(1, &m_positionBuf);
754*35238bceSAndroid Build Coastguard Worker     gl.genBuffers(1, &m_colorBuf);
755*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "Initialization failed");
756*35238bceSAndroid Build Coastguard Worker }
757*35238bceSAndroid Build Coastguard Worker 
~IndexArrayVerifier(void)758*35238bceSAndroid Build Coastguard Worker IndexArrayVerifier::~IndexArrayVerifier(void)
759*35238bceSAndroid Build Coastguard Worker {
760*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_renderCtx.getFunctions();
761*35238bceSAndroid Build Coastguard Worker 
762*35238bceSAndroid Build Coastguard Worker     if (m_vao)
763*35238bceSAndroid Build Coastguard Worker         gl.deleteVertexArrays(1, &m_vao);
764*35238bceSAndroid Build Coastguard Worker     if (m_positionBuf)
765*35238bceSAndroid Build Coastguard Worker         gl.deleteBuffers(1, &m_positionBuf);
766*35238bceSAndroid Build Coastguard Worker     if (m_colorBuf)
767*35238bceSAndroid Build Coastguard Worker         gl.deleteBuffers(1, &m_colorBuf);
768*35238bceSAndroid Build Coastguard Worker 
769*35238bceSAndroid Build Coastguard Worker     delete m_program;
770*35238bceSAndroid Build Coastguard Worker }
771*35238bceSAndroid Build Coastguard Worker 
computeIndexVerifierPositions(std::vector<tcu::Vec2> & dst)772*35238bceSAndroid Build Coastguard Worker static void computeIndexVerifierPositions(std::vector<tcu::Vec2> &dst)
773*35238bceSAndroid Build Coastguard Worker {
774*35238bceSAndroid Build Coastguard Worker     const int numPosX = 16;
775*35238bceSAndroid Build Coastguard Worker     const int numPosY = 16;
776*35238bceSAndroid Build Coastguard Worker 
777*35238bceSAndroid Build Coastguard Worker     dst.resize(numPosX * numPosY);
778*35238bceSAndroid Build Coastguard Worker 
779*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < numPosY; y++)
780*35238bceSAndroid Build Coastguard Worker     {
781*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < numPosX; x++)
782*35238bceSAndroid Build Coastguard Worker         {
783*35238bceSAndroid Build Coastguard Worker             float xf = float(x) / float(numPosX - 1);
784*35238bceSAndroid Build Coastguard Worker             float yf = float(y) / float(numPosY - 1);
785*35238bceSAndroid Build Coastguard Worker 
786*35238bceSAndroid Build Coastguard Worker             dst[y * numPosX + x] = tcu::Vec2(2.0f * xf - 1.0f, 2.0f * yf - 1.0f);
787*35238bceSAndroid Build Coastguard Worker         }
788*35238bceSAndroid Build Coastguard Worker     }
789*35238bceSAndroid Build Coastguard Worker }
790*35238bceSAndroid Build Coastguard Worker 
computeIndexVerifierColors(std::vector<tcu::Vec3> & dst)791*35238bceSAndroid Build Coastguard Worker static void computeIndexVerifierColors(std::vector<tcu::Vec3> &dst)
792*35238bceSAndroid Build Coastguard Worker {
793*35238bceSAndroid Build Coastguard Worker     const int numColors = 256;
794*35238bceSAndroid Build Coastguard Worker     const float minVal  = 0.1f;
795*35238bceSAndroid Build Coastguard Worker     const float maxVal  = 0.5f;
796*35238bceSAndroid Build Coastguard Worker     de::Random rnd(0xabc231);
797*35238bceSAndroid Build Coastguard Worker 
798*35238bceSAndroid Build Coastguard Worker     dst.resize(numColors);
799*35238bceSAndroid Build Coastguard Worker 
800*35238bceSAndroid Build Coastguard Worker     for (std::vector<tcu::Vec3>::iterator i = dst.begin(); i != dst.end(); ++i)
801*35238bceSAndroid Build Coastguard Worker     {
802*35238bceSAndroid Build Coastguard Worker         i->x() = rnd.getFloat(minVal, maxVal);
803*35238bceSAndroid Build Coastguard Worker         i->y() = rnd.getFloat(minVal, maxVal);
804*35238bceSAndroid Build Coastguard Worker         i->z() = rnd.getFloat(minVal, maxVal);
805*35238bceSAndroid Build Coastguard Worker     }
806*35238bceSAndroid Build Coastguard Worker }
807*35238bceSAndroid Build Coastguard Worker 
808*35238bceSAndroid Build Coastguard Worker template <typename T>
execVertexFetch(T * dst,const T * src,const uint8_t * indices,int numIndices)809*35238bceSAndroid Build Coastguard Worker static void execVertexFetch(T *dst, const T *src, const uint8_t *indices, int numIndices)
810*35238bceSAndroid Build Coastguard Worker {
811*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < numIndices; ++i)
812*35238bceSAndroid Build Coastguard Worker         dst[i] = src[indices[i]];
813*35238bceSAndroid Build Coastguard Worker }
814*35238bceSAndroid Build Coastguard Worker 
verify(uint32_t buffer,const uint8_t * refPtr,int offset,int numBytes)815*35238bceSAndroid Build Coastguard Worker bool IndexArrayVerifier::verify(uint32_t buffer, const uint8_t *refPtr, int offset, int numBytes)
816*35238bceSAndroid Build Coastguard Worker {
817*35238bceSAndroid Build Coastguard Worker     const tcu::RenderTarget &renderTarget = m_renderCtx.getRenderTarget();
818*35238bceSAndroid Build Coastguard Worker     const int viewportW                   = de::min<int>(INDEX_ARRAY_DRAW_VIEWPORT_WIDTH, renderTarget.getWidth());
819*35238bceSAndroid Build Coastguard Worker     const int viewportH                   = de::min<int>(INDEX_ARRAY_DRAW_VIEWPORT_HEIGHT, renderTarget.getHeight());
820*35238bceSAndroid Build Coastguard Worker     const int minBytesPerBatch            = 2;
821*35238bceSAndroid Build Coastguard Worker     const tcu::RGBA threshold(0, 0, 0, 0);
822*35238bceSAndroid Build Coastguard Worker 
823*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec2> positions;
824*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec3> colors;
825*35238bceSAndroid Build Coastguard Worker 
826*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec2> fetchedPos(MAX_LINES_PER_INDEX_ARRAY_DRAW + 1);
827*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec3> fetchedColor(MAX_LINES_PER_INDEX_ARRAY_DRAW + 1);
828*35238bceSAndroid Build Coastguard Worker 
829*35238bceSAndroid Build Coastguard Worker     tcu::Surface indexBufferImg(viewportW, viewportH);
830*35238bceSAndroid Build Coastguard Worker     tcu::Surface referenceImg(viewportW, viewportH);
831*35238bceSAndroid Build Coastguard Worker 
832*35238bceSAndroid Build Coastguard Worker     int numVerified = 0;
833*35238bceSAndroid Build Coastguard Worker     bool isOk       = true;
834*35238bceSAndroid Build Coastguard Worker 
835*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(sizeof(tcu::Vec2) == sizeof(float) * 2);
836*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(sizeof(tcu::Vec3) == sizeof(float) * 3);
837*35238bceSAndroid Build Coastguard Worker 
838*35238bceSAndroid Build Coastguard Worker     computeIndexVerifierPositions(positions);
839*35238bceSAndroid Build Coastguard Worker     computeIndexVerifierColors(colors);
840*35238bceSAndroid Build Coastguard Worker 
841*35238bceSAndroid Build Coastguard Worker     // Reset buffer bindings.
842*35238bceSAndroid Build Coastguard Worker     glBindVertexArray(m_vao);
843*35238bceSAndroid Build Coastguard Worker     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
844*35238bceSAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
845*35238bceSAndroid Build Coastguard Worker 
846*35238bceSAndroid Build Coastguard Worker     // Setup rendering state.
847*35238bceSAndroid Build Coastguard Worker     glViewport(0, 0, viewportW, viewportH);
848*35238bceSAndroid Build Coastguard Worker     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
849*35238bceSAndroid Build Coastguard Worker     glUseProgram(m_program->getProgram());
850*35238bceSAndroid Build Coastguard Worker     glEnableVertexAttribArray(m_posLoc);
851*35238bceSAndroid Build Coastguard Worker     glEnableVertexAttribArray(m_colorLoc);
852*35238bceSAndroid Build Coastguard Worker     glEnable(GL_BLEND);
853*35238bceSAndroid Build Coastguard Worker     glBlendFunc(GL_ONE, GL_ONE);
854*35238bceSAndroid Build Coastguard Worker     glBlendEquation(GL_FUNC_ADD);
855*35238bceSAndroid Build Coastguard Worker 
856*35238bceSAndroid Build Coastguard Worker     while (numVerified < numBytes)
857*35238bceSAndroid Build Coastguard Worker     {
858*35238bceSAndroid Build Coastguard Worker         int numRemaining     = numBytes - numVerified;
859*35238bceSAndroid Build Coastguard Worker         bool isLeftoverBatch = numRemaining < minBytesPerBatch;
860*35238bceSAndroid Build Coastguard Worker         int numBytesToVerify =
861*35238bceSAndroid Build Coastguard Worker             isLeftoverBatch ? minBytesPerBatch : de::min(MAX_LINES_PER_INDEX_ARRAY_DRAW + 1, numRemaining);
862*35238bceSAndroid Build Coastguard Worker         int curOffset       = isLeftoverBatch ? (numBytes - minBytesPerBatch) : numVerified;
863*35238bceSAndroid Build Coastguard Worker         string imageSetDesc = string("Bytes ") + de::toString(offset + curOffset) + " to " +
864*35238bceSAndroid Build Coastguard Worker                               de::toString(offset + curOffset + numBytesToVerify - 1);
865*35238bceSAndroid Build Coastguard Worker 
866*35238bceSAndroid Build Coastguard Worker         // Step 1: Render using index buffer.
867*35238bceSAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
868*35238bceSAndroid Build Coastguard Worker 
869*35238bceSAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, m_positionBuf);
870*35238bceSAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(positions.size() * sizeof(positions[0])), &positions[0],
871*35238bceSAndroid Build Coastguard Worker                      GL_STREAM_DRAW);
872*35238bceSAndroid Build Coastguard Worker         glVertexAttribPointer(m_posLoc, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL);
873*35238bceSAndroid Build Coastguard Worker 
874*35238bceSAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, m_colorBuf);
875*35238bceSAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(colors.size() * sizeof(colors[0])), &colors[0], GL_STREAM_DRAW);
876*35238bceSAndroid Build Coastguard Worker         glVertexAttribPointer(m_colorLoc, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
877*35238bceSAndroid Build Coastguard Worker 
878*35238bceSAndroid Build Coastguard Worker         glDrawElements(GL_LINE_STRIP, numBytesToVerify, GL_UNSIGNED_BYTE, (void *)(uintptr_t)(offset + curOffset));
879*35238bceSAndroid Build Coastguard Worker         glu::readPixels(m_renderCtx, 0, 0, indexBufferImg.getAccess());
880*35238bceSAndroid Build Coastguard Worker 
881*35238bceSAndroid Build Coastguard Worker         // Step 2: Do manual fetch and render without index buffer.
882*35238bceSAndroid Build Coastguard Worker         execVertexFetch(&fetchedPos[0], &positions[0], refPtr + offset + curOffset, numBytesToVerify);
883*35238bceSAndroid Build Coastguard Worker         execVertexFetch(&fetchedColor[0], &colors[0], refPtr + offset + curOffset, numBytesToVerify);
884*35238bceSAndroid Build Coastguard Worker 
885*35238bceSAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
886*35238bceSAndroid Build Coastguard Worker 
887*35238bceSAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, m_positionBuf);
888*35238bceSAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(fetchedPos.size() * sizeof(fetchedPos[0])), &fetchedPos[0],
889*35238bceSAndroid Build Coastguard Worker                      GL_STREAM_DRAW);
890*35238bceSAndroid Build Coastguard Worker         glVertexAttribPointer(m_posLoc, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL);
891*35238bceSAndroid Build Coastguard Worker 
892*35238bceSAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, m_colorBuf);
893*35238bceSAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(fetchedColor.size() * sizeof(fetchedColor[0])),
894*35238bceSAndroid Build Coastguard Worker                      &fetchedColor[0], GL_STREAM_DRAW);
895*35238bceSAndroid Build Coastguard Worker         glVertexAttribPointer(m_colorLoc, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
896*35238bceSAndroid Build Coastguard Worker 
897*35238bceSAndroid Build Coastguard Worker         glDrawArrays(GL_LINE_STRIP, 0, numBytesToVerify);
898*35238bceSAndroid Build Coastguard Worker         glu::readPixels(m_renderCtx, 0, 0, referenceImg.getAccess());
899*35238bceSAndroid Build Coastguard Worker 
900*35238bceSAndroid Build Coastguard Worker         if (!tcu::pixelThresholdCompare(m_log, "RenderResult", imageSetDesc.c_str(), referenceImg, indexBufferImg,
901*35238bceSAndroid Build Coastguard Worker                                         threshold, tcu::COMPARE_LOG_RESULT))
902*35238bceSAndroid Build Coastguard Worker         {
903*35238bceSAndroid Build Coastguard Worker             isOk = false;
904*35238bceSAndroid Build Coastguard Worker             break;
905*35238bceSAndroid Build Coastguard Worker         }
906*35238bceSAndroid Build Coastguard Worker 
907*35238bceSAndroid Build Coastguard Worker         numVerified += isLeftoverBatch ? numRemaining : numBytesToVerify;
908*35238bceSAndroid Build Coastguard Worker     }
909*35238bceSAndroid Build Coastguard Worker 
910*35238bceSAndroid Build Coastguard Worker     glBindVertexArray(0);
911*35238bceSAndroid Build Coastguard Worker 
912*35238bceSAndroid Build Coastguard Worker     return isOk;
913*35238bceSAndroid Build Coastguard Worker }
914*35238bceSAndroid Build Coastguard Worker 
getWriteTypeDescription(WriteType write)915*35238bceSAndroid Build Coastguard Worker const char *getWriteTypeDescription(WriteType write)
916*35238bceSAndroid Build Coastguard Worker {
917*35238bceSAndroid Build Coastguard Worker     static const char *s_desc[] = {"glBufferSubData()", "glMapBufferRange()", "transform feedback",
918*35238bceSAndroid Build Coastguard Worker                                    "glReadPixels() into PBO binding"};
919*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<WRITE_LAST>(s_desc, write);
920*35238bceSAndroid Build Coastguard Worker }
921*35238bceSAndroid Build Coastguard Worker 
getVerifyTypeDescription(VerifyType verify)922*35238bceSAndroid Build Coastguard Worker const char *getVerifyTypeDescription(VerifyType verify)
923*35238bceSAndroid Build Coastguard Worker {
924*35238bceSAndroid Build Coastguard Worker     static const char *s_desc[] = {"rendering as vertex data", "rendering as index data",
925*35238bceSAndroid Build Coastguard Worker                                    "reading in shader as uniform buffer data", "using as PBO and uploading to texture",
926*35238bceSAndroid Build Coastguard Worker                                    "reading back using glMapBufferRange()"};
927*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<VERIFY_LAST>(s_desc, verify);
928*35238bceSAndroid Build Coastguard Worker }
929*35238bceSAndroid Build Coastguard Worker 
930*35238bceSAndroid Build Coastguard Worker } // namespace BufferTestUtil
931*35238bceSAndroid Build Coastguard Worker } // namespace gls
932*35238bceSAndroid Build Coastguard Worker } // namespace deqp
933