1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program OpenGL ES 3.1 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 Vertex attribute binding stress tests.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "es31sVertexAttributeBindingTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "tcuVector.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "gluCallLogWrapper.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "gluObjectWrapper.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
38*35238bceSAndroid Build Coastguard Worker
39*35238bceSAndroid Build Coastguard Worker namespace deqp
40*35238bceSAndroid Build Coastguard Worker {
41*35238bceSAndroid Build Coastguard Worker namespace gles31
42*35238bceSAndroid Build Coastguard Worker {
43*35238bceSAndroid Build Coastguard Worker namespace Stress
44*35238bceSAndroid Build Coastguard Worker {
45*35238bceSAndroid Build Coastguard Worker namespace
46*35238bceSAndroid Build Coastguard Worker {
47*35238bceSAndroid Build Coastguard Worker
48*35238bceSAndroid Build Coastguard Worker static const char *const s_vertexSource = "#version 310 es\n"
49*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_position;\n"
50*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
51*35238bceSAndroid Build Coastguard Worker "{\n"
52*35238bceSAndroid Build Coastguard Worker " gl_Position = a_position;\n"
53*35238bceSAndroid Build Coastguard Worker "}\n";
54*35238bceSAndroid Build Coastguard Worker
55*35238bceSAndroid Build Coastguard Worker static const char *const s_fragmentSource = "#version 310 es\n"
56*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out mediump vec4 fragColor;\n"
57*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
58*35238bceSAndroid Build Coastguard Worker "{\n"
59*35238bceSAndroid Build Coastguard Worker " fragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
60*35238bceSAndroid Build Coastguard Worker "}\n";
61*35238bceSAndroid Build Coastguard Worker
62*35238bceSAndroid Build Coastguard Worker static const char *const s_colorFragmentShader = "#version 310 es\n"
63*35238bceSAndroid Build Coastguard Worker "in mediump vec4 v_color;\n"
64*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out mediump vec4 fragColor;\n"
65*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
66*35238bceSAndroid Build Coastguard Worker "{\n"
67*35238bceSAndroid Build Coastguard Worker " fragColor = v_color;\n"
68*35238bceSAndroid Build Coastguard Worker "}\n";
69*35238bceSAndroid Build Coastguard Worker
70*35238bceSAndroid Build Coastguard Worker // Verifies image contains only yellow or greeen, or a linear combination
71*35238bceSAndroid Build Coastguard Worker // of these colors.
verifyImageYellowGreen(const tcu::Surface & image,tcu::TestLog & log,bool logImageOnSuccess)72*35238bceSAndroid Build Coastguard Worker static bool verifyImageYellowGreen(const tcu::Surface &image, tcu::TestLog &log, bool logImageOnSuccess)
73*35238bceSAndroid Build Coastguard Worker {
74*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
75*35238bceSAndroid Build Coastguard Worker
76*35238bceSAndroid Build Coastguard Worker const int colorThreshold = 20;
77*35238bceSAndroid Build Coastguard Worker
78*35238bceSAndroid Build Coastguard Worker tcu::Surface error(image.getWidth(), image.getHeight());
79*35238bceSAndroid Build Coastguard Worker bool isOk = true;
80*35238bceSAndroid Build Coastguard Worker
81*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Verifying image contents." << TestLog::EndMessage;
82*35238bceSAndroid Build Coastguard Worker
83*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < image.getHeight(); y++)
84*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < image.getWidth(); x++)
85*35238bceSAndroid Build Coastguard Worker {
86*35238bceSAndroid Build Coastguard Worker const tcu::RGBA pixel = image.getPixel(x, y);
87*35238bceSAndroid Build Coastguard Worker bool pixelOk = true;
88*35238bceSAndroid Build Coastguard Worker
89*35238bceSAndroid Build Coastguard Worker // Any pixel with !(G ~= 255) is faulty (not a linear combinations of green and yellow)
90*35238bceSAndroid Build Coastguard Worker if (de::abs(pixel.getGreen() - 255) > colorThreshold)
91*35238bceSAndroid Build Coastguard Worker pixelOk = false;
92*35238bceSAndroid Build Coastguard Worker
93*35238bceSAndroid Build Coastguard Worker // Any pixel with !(B ~= 0) is faulty (not a linear combinations of green and yellow)
94*35238bceSAndroid Build Coastguard Worker if (de::abs(pixel.getBlue() - 0) > colorThreshold)
95*35238bceSAndroid Build Coastguard Worker pixelOk = false;
96*35238bceSAndroid Build Coastguard Worker
97*35238bceSAndroid Build Coastguard Worker error.setPixel(x, y, (pixelOk) ? (tcu::RGBA(0, 255, 0, 255)) : (tcu::RGBA(255, 0, 0, 255)));
98*35238bceSAndroid Build Coastguard Worker isOk = isOk && pixelOk;
99*35238bceSAndroid Build Coastguard Worker }
100*35238bceSAndroid Build Coastguard Worker
101*35238bceSAndroid Build Coastguard Worker if (!isOk)
102*35238bceSAndroid Build Coastguard Worker {
103*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Image verification failed." << TestLog::EndMessage;
104*35238bceSAndroid Build Coastguard Worker log << TestLog::ImageSet("Verfication result", "Result of rendering")
105*35238bceSAndroid Build Coastguard Worker << TestLog::Image("Result", "Result", image) << TestLog::Image("ErrorMask", "Error mask", error)
106*35238bceSAndroid Build Coastguard Worker << TestLog::EndImageSet;
107*35238bceSAndroid Build Coastguard Worker }
108*35238bceSAndroid Build Coastguard Worker else
109*35238bceSAndroid Build Coastguard Worker {
110*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Image verification passed." << TestLog::EndMessage;
111*35238bceSAndroid Build Coastguard Worker
112*35238bceSAndroid Build Coastguard Worker if (logImageOnSuccess)
113*35238bceSAndroid Build Coastguard Worker log << TestLog::ImageSet("Verfication result", "Result of rendering")
114*35238bceSAndroid Build Coastguard Worker << TestLog::Image("Result", "Result", image) << TestLog::EndImageSet;
115*35238bceSAndroid Build Coastguard Worker }
116*35238bceSAndroid Build Coastguard Worker
117*35238bceSAndroid Build Coastguard Worker return isOk;
118*35238bceSAndroid Build Coastguard Worker }
119*35238bceSAndroid Build Coastguard Worker
120*35238bceSAndroid Build Coastguard Worker class BindingRenderCase : public TestCase
121*35238bceSAndroid Build Coastguard Worker {
122*35238bceSAndroid Build Coastguard Worker public:
123*35238bceSAndroid Build Coastguard Worker enum
124*35238bceSAndroid Build Coastguard Worker {
125*35238bceSAndroid Build Coastguard Worker TEST_RENDER_SIZE = 64
126*35238bceSAndroid Build Coastguard Worker };
127*35238bceSAndroid Build Coastguard Worker
128*35238bceSAndroid Build Coastguard Worker BindingRenderCase(Context &ctx, const char *name, const char *desc, bool unalignedData);
129*35238bceSAndroid Build Coastguard Worker virtual ~BindingRenderCase(void);
130*35238bceSAndroid Build Coastguard Worker
131*35238bceSAndroid Build Coastguard Worker virtual void init(void);
132*35238bceSAndroid Build Coastguard Worker virtual void deinit(void);
133*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
134*35238bceSAndroid Build Coastguard Worker
135*35238bceSAndroid Build Coastguard Worker private:
136*35238bceSAndroid Build Coastguard Worker virtual void renderTo(tcu::Surface &dst) = 0;
137*35238bceSAndroid Build Coastguard Worker virtual void createBuffers(void) = 0;
138*35238bceSAndroid Build Coastguard Worker virtual void createShader(void) = 0;
139*35238bceSAndroid Build Coastguard Worker
140*35238bceSAndroid Build Coastguard Worker protected:
141*35238bceSAndroid Build Coastguard Worker const bool m_unalignedData;
142*35238bceSAndroid Build Coastguard Worker glw::GLuint m_vao;
143*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_program;
144*35238bceSAndroid Build Coastguard Worker };
145*35238bceSAndroid Build Coastguard Worker
BindingRenderCase(Context & ctx,const char * name,const char * desc,bool unalignedData)146*35238bceSAndroid Build Coastguard Worker BindingRenderCase::BindingRenderCase(Context &ctx, const char *name, const char *desc, bool unalignedData)
147*35238bceSAndroid Build Coastguard Worker : TestCase(ctx, name, desc)
148*35238bceSAndroid Build Coastguard Worker , m_unalignedData(unalignedData)
149*35238bceSAndroid Build Coastguard Worker , m_vao(0)
150*35238bceSAndroid Build Coastguard Worker , m_program(DE_NULL)
151*35238bceSAndroid Build Coastguard Worker {
152*35238bceSAndroid Build Coastguard Worker }
153*35238bceSAndroid Build Coastguard Worker
~BindingRenderCase(void)154*35238bceSAndroid Build Coastguard Worker BindingRenderCase::~BindingRenderCase(void)
155*35238bceSAndroid Build Coastguard Worker {
156*35238bceSAndroid Build Coastguard Worker deinit();
157*35238bceSAndroid Build Coastguard Worker }
158*35238bceSAndroid Build Coastguard Worker
init(void)159*35238bceSAndroid Build Coastguard Worker void BindingRenderCase::init(void)
160*35238bceSAndroid Build Coastguard Worker {
161*35238bceSAndroid Build Coastguard Worker // check requirements
162*35238bceSAndroid Build Coastguard Worker if (m_context.getRenderTarget().getWidth() < TEST_RENDER_SIZE ||
163*35238bceSAndroid Build Coastguard Worker m_context.getRenderTarget().getHeight() < TEST_RENDER_SIZE)
164*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Test requires at least " + de::toString<int>(TEST_RENDER_SIZE) + "x" +
165*35238bceSAndroid Build Coastguard Worker de::toString<int>(TEST_RENDER_SIZE) + " render target");
166*35238bceSAndroid Build Coastguard Worker
167*35238bceSAndroid Build Coastguard Worker // resources
168*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().genVertexArrays(1, &m_vao);
169*35238bceSAndroid Build Coastguard Worker if (m_context.getRenderContext().getFunctions().getError() != GL_NO_ERROR)
170*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not gen vao");
171*35238bceSAndroid Build Coastguard Worker
172*35238bceSAndroid Build Coastguard Worker createBuffers();
173*35238bceSAndroid Build Coastguard Worker createShader();
174*35238bceSAndroid Build Coastguard Worker }
175*35238bceSAndroid Build Coastguard Worker
deinit(void)176*35238bceSAndroid Build Coastguard Worker void BindingRenderCase::deinit(void)
177*35238bceSAndroid Build Coastguard Worker {
178*35238bceSAndroid Build Coastguard Worker if (m_vao)
179*35238bceSAndroid Build Coastguard Worker {
180*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteVertexArrays(1, &m_vao);
181*35238bceSAndroid Build Coastguard Worker m_vao = 0;
182*35238bceSAndroid Build Coastguard Worker }
183*35238bceSAndroid Build Coastguard Worker
184*35238bceSAndroid Build Coastguard Worker delete m_program;
185*35238bceSAndroid Build Coastguard Worker m_program = DE_NULL;
186*35238bceSAndroid Build Coastguard Worker }
187*35238bceSAndroid Build Coastguard Worker
iterate(void)188*35238bceSAndroid Build Coastguard Worker BindingRenderCase::IterateResult BindingRenderCase::iterate(void)
189*35238bceSAndroid Build Coastguard Worker {
190*35238bceSAndroid Build Coastguard Worker tcu::Surface surface(TEST_RENDER_SIZE, TEST_RENDER_SIZE);
191*35238bceSAndroid Build Coastguard Worker
192*35238bceSAndroid Build Coastguard Worker // draw pattern
193*35238bceSAndroid Build Coastguard Worker
194*35238bceSAndroid Build Coastguard Worker renderTo(surface);
195*35238bceSAndroid Build Coastguard Worker
196*35238bceSAndroid Build Coastguard Worker // verify results
197*35238bceSAndroid Build Coastguard Worker
198*35238bceSAndroid Build Coastguard Worker if (verifyImageYellowGreen(surface, m_testCtx.getLog(), false))
199*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
200*35238bceSAndroid Build Coastguard Worker else if (m_unalignedData)
201*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned data");
202*35238bceSAndroid Build Coastguard Worker else
203*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
204*35238bceSAndroid Build Coastguard Worker
205*35238bceSAndroid Build Coastguard Worker return STOP;
206*35238bceSAndroid Build Coastguard Worker }
207*35238bceSAndroid Build Coastguard Worker
208*35238bceSAndroid Build Coastguard Worker class SingleBindingCase : public BindingRenderCase
209*35238bceSAndroid Build Coastguard Worker {
210*35238bceSAndroid Build Coastguard Worker public:
211*35238bceSAndroid Build Coastguard Worker enum CaseFlag
212*35238bceSAndroid Build Coastguard Worker {
213*35238bceSAndroid Build Coastguard Worker FLAG_ATTRIB_UNALIGNED = (1 << 0), // !< unalign attributes with relativeOffset
214*35238bceSAndroid Build Coastguard Worker FLAG_ATTRIB_ALIGNED =
215*35238bceSAndroid Build Coastguard Worker (1 << 1), // !< align attributes with relativeOffset to the buffer begin (and not buffer offset)
216*35238bceSAndroid Build Coastguard Worker FLAG_ATTRIBS_MULTIPLE_ELEMS = (1 << 2), // !< use multiple attribute elements
217*35238bceSAndroid Build Coastguard Worker FLAG_ATTRIBS_SHARED_ELEMS =
218*35238bceSAndroid Build Coastguard Worker (1 << 3), // !< use multiple shared attribute elements. xyzw & rgba stored as (x, y, zr, wg, b, a)
219*35238bceSAndroid Build Coastguard Worker
220*35238bceSAndroid Build Coastguard Worker FLAG_BUF_ALIGNED_OFFSET = (1 << 4), // !< use aligned offset to the buffer object
221*35238bceSAndroid Build Coastguard Worker FLAG_BUF_UNALIGNED_OFFSET = (1 << 5), // !< use unaligned offset to the buffer object
222*35238bceSAndroid Build Coastguard Worker FLAG_BUF_UNALIGNED_STRIDE = (1 << 6), // !< unalign buffer elements
223*35238bceSAndroid Build Coastguard Worker };
224*35238bceSAndroid Build Coastguard Worker SingleBindingCase(Context &ctx, const char *name, int flags);
225*35238bceSAndroid Build Coastguard Worker ~SingleBindingCase(void);
226*35238bceSAndroid Build Coastguard Worker
227*35238bceSAndroid Build Coastguard Worker void init(void);
228*35238bceSAndroid Build Coastguard Worker void deinit(void);
229*35238bceSAndroid Build Coastguard Worker
230*35238bceSAndroid Build Coastguard Worker private:
231*35238bceSAndroid Build Coastguard Worker struct TestSpec
232*35238bceSAndroid Build Coastguard Worker {
233*35238bceSAndroid Build Coastguard Worker int bufferOffset;
234*35238bceSAndroid Build Coastguard Worker int bufferStride;
235*35238bceSAndroid Build Coastguard Worker int positionAttrOffset;
236*35238bceSAndroid Build Coastguard Worker int colorAttrOffset;
237*35238bceSAndroid Build Coastguard Worker bool hasColorAttr;
238*35238bceSAndroid Build Coastguard Worker };
239*35238bceSAndroid Build Coastguard Worker
240*35238bceSAndroid Build Coastguard Worker enum
241*35238bceSAndroid Build Coastguard Worker {
242*35238bceSAndroid Build Coastguard Worker GRID_SIZE = 20
243*35238bceSAndroid Build Coastguard Worker };
244*35238bceSAndroid Build Coastguard Worker
245*35238bceSAndroid Build Coastguard Worker void renderTo(tcu::Surface &dst);
246*35238bceSAndroid Build Coastguard Worker
247*35238bceSAndroid Build Coastguard Worker static TestSpec genTestSpec(int flags);
248*35238bceSAndroid Build Coastguard Worker static std::string genTestDescription(int flags);
249*35238bceSAndroid Build Coastguard Worker static bool isDataUnaligned(int flags);
250*35238bceSAndroid Build Coastguard Worker
251*35238bceSAndroid Build Coastguard Worker void createBuffers(void);
252*35238bceSAndroid Build Coastguard Worker void createShader(void);
253*35238bceSAndroid Build Coastguard Worker std::string genVertexSource(void);
254*35238bceSAndroid Build Coastguard Worker
255*35238bceSAndroid Build Coastguard Worker const TestSpec m_spec;
256*35238bceSAndroid Build Coastguard Worker glw::GLuint m_buf;
257*35238bceSAndroid Build Coastguard Worker };
258*35238bceSAndroid Build Coastguard Worker
SingleBindingCase(Context & ctx,const char * name,int flags)259*35238bceSAndroid Build Coastguard Worker SingleBindingCase::SingleBindingCase(Context &ctx, const char *name, int flags)
260*35238bceSAndroid Build Coastguard Worker : BindingRenderCase(ctx, name, genTestDescription(flags).c_str(), isDataUnaligned(flags))
261*35238bceSAndroid Build Coastguard Worker , m_spec(genTestSpec(flags))
262*35238bceSAndroid Build Coastguard Worker , m_buf(0)
263*35238bceSAndroid Build Coastguard Worker {
264*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!((flags & FLAG_ATTRIB_UNALIGNED) && (flags & FLAG_ATTRIB_ALIGNED)));
265*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!((flags & FLAG_ATTRIB_ALIGNED) && (flags & FLAG_BUF_UNALIGNED_STRIDE)));
266*35238bceSAndroid Build Coastguard Worker
267*35238bceSAndroid Build Coastguard Worker DE_ASSERT(isDataUnaligned(flags));
268*35238bceSAndroid Build Coastguard Worker }
269*35238bceSAndroid Build Coastguard Worker
~SingleBindingCase(void)270*35238bceSAndroid Build Coastguard Worker SingleBindingCase::~SingleBindingCase(void)
271*35238bceSAndroid Build Coastguard Worker {
272*35238bceSAndroid Build Coastguard Worker deinit();
273*35238bceSAndroid Build Coastguard Worker }
274*35238bceSAndroid Build Coastguard Worker
init(void)275*35238bceSAndroid Build Coastguard Worker void SingleBindingCase::init(void)
276*35238bceSAndroid Build Coastguard Worker {
277*35238bceSAndroid Build Coastguard Worker // log what we are trying to do
278*35238bceSAndroid Build Coastguard Worker
279*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Rendering " << (int)GRID_SIZE << "x" << (int)GRID_SIZE << " grid.\n"
280*35238bceSAndroid Build Coastguard Worker << "Buffer format:\n"
281*35238bceSAndroid Build Coastguard Worker << " bufferOffset: " << m_spec.bufferOffset << "\n"
282*35238bceSAndroid Build Coastguard Worker << " bufferStride: " << m_spec.bufferStride << "\n"
283*35238bceSAndroid Build Coastguard Worker << "Vertex position format:\n"
284*35238bceSAndroid Build Coastguard Worker << " type: float4\n"
285*35238bceSAndroid Build Coastguard Worker << " offset: " << m_spec.positionAttrOffset << "\n"
286*35238bceSAndroid Build Coastguard Worker << " total offset: " << m_spec.bufferOffset + m_spec.positionAttrOffset << "\n"
287*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
288*35238bceSAndroid Build Coastguard Worker
289*35238bceSAndroid Build Coastguard Worker if (m_spec.hasColorAttr)
290*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Color:\n"
291*35238bceSAndroid Build Coastguard Worker << " type: float4\n"
292*35238bceSAndroid Build Coastguard Worker << " offset: " << m_spec.colorAttrOffset << "\n"
293*35238bceSAndroid Build Coastguard Worker << " total offset: " << m_spec.bufferOffset + m_spec.colorAttrOffset << "\n"
294*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
295*35238bceSAndroid Build Coastguard Worker // init
296*35238bceSAndroid Build Coastguard Worker
297*35238bceSAndroid Build Coastguard Worker BindingRenderCase::init();
298*35238bceSAndroid Build Coastguard Worker }
299*35238bceSAndroid Build Coastguard Worker
deinit(void)300*35238bceSAndroid Build Coastguard Worker void SingleBindingCase::deinit(void)
301*35238bceSAndroid Build Coastguard Worker {
302*35238bceSAndroid Build Coastguard Worker if (m_buf)
303*35238bceSAndroid Build Coastguard Worker {
304*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buf);
305*35238bceSAndroid Build Coastguard Worker m_buf = 0;
306*35238bceSAndroid Build Coastguard Worker }
307*35238bceSAndroid Build Coastguard Worker
308*35238bceSAndroid Build Coastguard Worker BindingRenderCase::deinit();
309*35238bceSAndroid Build Coastguard Worker }
310*35238bceSAndroid Build Coastguard Worker
renderTo(tcu::Surface & dst)311*35238bceSAndroid Build Coastguard Worker void SingleBindingCase::renderTo(tcu::Surface &dst)
312*35238bceSAndroid Build Coastguard Worker {
313*35238bceSAndroid Build Coastguard Worker glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
314*35238bceSAndroid Build Coastguard Worker const int positionLoc = gl.glGetAttribLocation(m_program->getProgram(), "a_position");
315*35238bceSAndroid Build Coastguard Worker const int colorLoc = gl.glGetAttribLocation(m_program->getProgram(), "a_color");
316*35238bceSAndroid Build Coastguard Worker const int colorUniformLoc = gl.glGetUniformLocation(m_program->getProgram(), "u_color");
317*35238bceSAndroid Build Coastguard Worker
318*35238bceSAndroid Build Coastguard Worker gl.enableLogging(true);
319*35238bceSAndroid Build Coastguard Worker
320*35238bceSAndroid Build Coastguard Worker gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
321*35238bceSAndroid Build Coastguard Worker gl.glClear(GL_COLOR_BUFFER_BIT);
322*35238bceSAndroid Build Coastguard Worker gl.glViewport(0, 0, dst.getWidth(), dst.getHeight());
323*35238bceSAndroid Build Coastguard Worker gl.glBindVertexArray(m_vao);
324*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.glGetError(), "set vao");
325*35238bceSAndroid Build Coastguard Worker
326*35238bceSAndroid Build Coastguard Worker gl.glUseProgram(m_program->getProgram());
327*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.glGetError(), "use program");
328*35238bceSAndroid Build Coastguard Worker
329*35238bceSAndroid Build Coastguard Worker if (m_spec.hasColorAttr)
330*35238bceSAndroid Build Coastguard Worker {
331*35238bceSAndroid Build Coastguard Worker gl.glBindVertexBuffer(3, m_buf, m_spec.bufferOffset, m_spec.bufferStride);
332*35238bceSAndroid Build Coastguard Worker
333*35238bceSAndroid Build Coastguard Worker gl.glVertexAttribBinding(positionLoc, 3);
334*35238bceSAndroid Build Coastguard Worker gl.glVertexAttribFormat(positionLoc, 4, GL_FLOAT, GL_FALSE, m_spec.positionAttrOffset);
335*35238bceSAndroid Build Coastguard Worker gl.glEnableVertexAttribArray(positionLoc);
336*35238bceSAndroid Build Coastguard Worker
337*35238bceSAndroid Build Coastguard Worker gl.glVertexAttribBinding(colorLoc, 3);
338*35238bceSAndroid Build Coastguard Worker gl.glVertexAttribFormat(colorLoc, 4, GL_FLOAT, GL_FALSE, m_spec.colorAttrOffset);
339*35238bceSAndroid Build Coastguard Worker gl.glEnableVertexAttribArray(colorLoc);
340*35238bceSAndroid Build Coastguard Worker
341*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.glGetError(), "set va");
342*35238bceSAndroid Build Coastguard Worker
343*35238bceSAndroid Build Coastguard Worker gl.glDrawArrays(GL_TRIANGLES, 0, GRID_SIZE * GRID_SIZE * 6);
344*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.glGetError(), "draw");
345*35238bceSAndroid Build Coastguard Worker }
346*35238bceSAndroid Build Coastguard Worker else
347*35238bceSAndroid Build Coastguard Worker {
348*35238bceSAndroid Build Coastguard Worker gl.glBindVertexBuffer(3, m_buf, m_spec.bufferOffset, m_spec.bufferStride);
349*35238bceSAndroid Build Coastguard Worker gl.glVertexAttribBinding(positionLoc, 3);
350*35238bceSAndroid Build Coastguard Worker gl.glVertexAttribFormat(positionLoc, 4, GL_FLOAT, GL_FALSE, m_spec.positionAttrOffset);
351*35238bceSAndroid Build Coastguard Worker gl.glEnableVertexAttribArray(positionLoc);
352*35238bceSAndroid Build Coastguard Worker
353*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.glGetError(), "set va");
354*35238bceSAndroid Build Coastguard Worker gl.glUniform4f(colorUniformLoc, 0.0f, 1.0f, 0.0f, 1.0f);
355*35238bceSAndroid Build Coastguard Worker
356*35238bceSAndroid Build Coastguard Worker gl.glDrawArrays(GL_TRIANGLES, 0, GRID_SIZE * GRID_SIZE * 6);
357*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.glGetError(), "draw");
358*35238bceSAndroid Build Coastguard Worker }
359*35238bceSAndroid Build Coastguard Worker
360*35238bceSAndroid Build Coastguard Worker gl.glFinish();
361*35238bceSAndroid Build Coastguard Worker gl.glBindVertexArray(0);
362*35238bceSAndroid Build Coastguard Worker gl.glUseProgram(0);
363*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.glGetError(), "clean");
364*35238bceSAndroid Build Coastguard Worker
365*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
366*35238bceSAndroid Build Coastguard Worker }
367*35238bceSAndroid Build Coastguard Worker
genTestSpec(int flags)368*35238bceSAndroid Build Coastguard Worker SingleBindingCase::TestSpec SingleBindingCase::genTestSpec(int flags)
369*35238bceSAndroid Build Coastguard Worker {
370*35238bceSAndroid Build Coastguard Worker const int datumSize = 4;
371*35238bceSAndroid Build Coastguard Worker const int bufferOffset = (flags & FLAG_BUF_ALIGNED_OFFSET) ? (32) :
372*35238bceSAndroid Build Coastguard Worker (flags & FLAG_BUF_UNALIGNED_OFFSET) ? (19) :
373*35238bceSAndroid Build Coastguard Worker (0);
374*35238bceSAndroid Build Coastguard Worker const int attrBufAlignment = ((bufferOffset % datumSize) == 0) ? (0) : (datumSize - (bufferOffset % datumSize));
375*35238bceSAndroid Build Coastguard Worker const int positionAttrOffset = (flags & FLAG_ATTRIB_UNALIGNED) ? (3) :
376*35238bceSAndroid Build Coastguard Worker (flags & FLAG_ATTRIB_ALIGNED) ? (attrBufAlignment) :
377*35238bceSAndroid Build Coastguard Worker (0);
378*35238bceSAndroid Build Coastguard Worker const bool hasColorAttr = (flags & FLAG_ATTRIBS_SHARED_ELEMS) || (flags & FLAG_ATTRIBS_MULTIPLE_ELEMS);
379*35238bceSAndroid Build Coastguard Worker const int colorAttrOffset = (flags & FLAG_ATTRIBS_SHARED_ELEMS) ? (2 * datumSize) :
380*35238bceSAndroid Build Coastguard Worker (flags & FLAG_ATTRIBS_MULTIPLE_ELEMS) ? (4 * datumSize) :
381*35238bceSAndroid Build Coastguard Worker (-1);
382*35238bceSAndroid Build Coastguard Worker
383*35238bceSAndroid Build Coastguard Worker const int bufferStrideBase = de::max(positionAttrOffset + 4 * datumSize, colorAttrOffset + 4 * datumSize);
384*35238bceSAndroid Build Coastguard Worker const int bufferStrideAlignment =
385*35238bceSAndroid Build Coastguard Worker ((bufferStrideBase % datumSize) == 0) ? (0) : (datumSize - (bufferStrideBase % datumSize));
386*35238bceSAndroid Build Coastguard Worker const int bufferStridePadding =
387*35238bceSAndroid Build Coastguard Worker ((flags & FLAG_BUF_UNALIGNED_STRIDE) && deIsAligned32(bufferStrideBase, datumSize)) ? (13) :
388*35238bceSAndroid Build Coastguard Worker (!(flags & FLAG_BUF_UNALIGNED_STRIDE) && !deIsAligned32(bufferStrideBase, datumSize)) ?
389*35238bceSAndroid Build Coastguard Worker (bufferStrideAlignment) :
390*35238bceSAndroid Build Coastguard Worker (0);
391*35238bceSAndroid Build Coastguard Worker
392*35238bceSAndroid Build Coastguard Worker TestSpec spec;
393*35238bceSAndroid Build Coastguard Worker
394*35238bceSAndroid Build Coastguard Worker spec.bufferOffset = bufferOffset;
395*35238bceSAndroid Build Coastguard Worker spec.bufferStride = bufferStrideBase + bufferStridePadding;
396*35238bceSAndroid Build Coastguard Worker spec.positionAttrOffset = positionAttrOffset;
397*35238bceSAndroid Build Coastguard Worker spec.colorAttrOffset = colorAttrOffset;
398*35238bceSAndroid Build Coastguard Worker spec.hasColorAttr = hasColorAttr;
399*35238bceSAndroid Build Coastguard Worker
400*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_ATTRIB_UNALIGNED)
401*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!deIsAligned32(spec.bufferOffset + spec.positionAttrOffset, datumSize));
402*35238bceSAndroid Build Coastguard Worker else if (flags & FLAG_ATTRIB_ALIGNED)
403*35238bceSAndroid Build Coastguard Worker DE_ASSERT(deIsAligned32(spec.bufferOffset + spec.positionAttrOffset, datumSize));
404*35238bceSAndroid Build Coastguard Worker
405*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_BUF_UNALIGNED_STRIDE)
406*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!deIsAligned32(spec.bufferStride, datumSize));
407*35238bceSAndroid Build Coastguard Worker else
408*35238bceSAndroid Build Coastguard Worker DE_ASSERT(deIsAligned32(spec.bufferStride, datumSize));
409*35238bceSAndroid Build Coastguard Worker
410*35238bceSAndroid Build Coastguard Worker return spec;
411*35238bceSAndroid Build Coastguard Worker }
412*35238bceSAndroid Build Coastguard Worker
genTestDescription(int flags)413*35238bceSAndroid Build Coastguard Worker std::string SingleBindingCase::genTestDescription(int flags)
414*35238bceSAndroid Build Coastguard Worker {
415*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
416*35238bceSAndroid Build Coastguard Worker buf << "draw test pattern";
417*35238bceSAndroid Build Coastguard Worker
418*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_ATTRIB_UNALIGNED)
419*35238bceSAndroid Build Coastguard Worker buf << ", attribute offset (unaligned)";
420*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_ATTRIB_ALIGNED)
421*35238bceSAndroid Build Coastguard Worker buf << ", attribute offset (aligned)";
422*35238bceSAndroid Build Coastguard Worker
423*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_ATTRIBS_MULTIPLE_ELEMS)
424*35238bceSAndroid Build Coastguard Worker buf << ", 2 attributes";
425*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_ATTRIBS_SHARED_ELEMS)
426*35238bceSAndroid Build Coastguard Worker buf << ", 2 attributes (some components shared)";
427*35238bceSAndroid Build Coastguard Worker
428*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_BUF_ALIGNED_OFFSET)
429*35238bceSAndroid Build Coastguard Worker buf << ", buffer offset aligned";
430*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_BUF_UNALIGNED_OFFSET)
431*35238bceSAndroid Build Coastguard Worker buf << ", buffer offset unaligned";
432*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_BUF_UNALIGNED_STRIDE)
433*35238bceSAndroid Build Coastguard Worker buf << ", buffer stride unaligned";
434*35238bceSAndroid Build Coastguard Worker
435*35238bceSAndroid Build Coastguard Worker return buf.str();
436*35238bceSAndroid Build Coastguard Worker }
437*35238bceSAndroid Build Coastguard Worker
isDataUnaligned(int flags)438*35238bceSAndroid Build Coastguard Worker bool SingleBindingCase::isDataUnaligned(int flags)
439*35238bceSAndroid Build Coastguard Worker {
440*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_ATTRIB_UNALIGNED)
441*35238bceSAndroid Build Coastguard Worker return true;
442*35238bceSAndroid Build Coastguard Worker if (flags & FLAG_ATTRIB_ALIGNED)
443*35238bceSAndroid Build Coastguard Worker return false;
444*35238bceSAndroid Build Coastguard Worker
445*35238bceSAndroid Build Coastguard Worker return (flags & FLAG_BUF_UNALIGNED_OFFSET) || (flags & FLAG_BUF_UNALIGNED_STRIDE);
446*35238bceSAndroid Build Coastguard Worker }
447*35238bceSAndroid Build Coastguard Worker
createBuffers(void)448*35238bceSAndroid Build Coastguard Worker void SingleBindingCase::createBuffers(void)
449*35238bceSAndroid Build Coastguard Worker {
450*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
451*35238bceSAndroid Build Coastguard Worker std::vector<uint8_t> dataBuf(m_spec.bufferOffset + m_spec.bufferStride * GRID_SIZE * GRID_SIZE * 6);
452*35238bceSAndroid Build Coastguard Worker
453*35238bceSAndroid Build Coastguard Worker // In interleaved mode color rg and position zw are the same. Select "good" values for r and g
454*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 colorA(0.0f, 1.0f, 0.0f, 1.0f);
455*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 colorB(0.5f, 1.0f, 0.0f, 1.0f);
456*35238bceSAndroid Build Coastguard Worker
457*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < GRID_SIZE; ++y)
458*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < GRID_SIZE; ++x)
459*35238bceSAndroid Build Coastguard Worker {
460*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 &color = ((x + y) % 2 == 0) ? (colorA) : (colorB);
461*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 positions[6] = {
462*35238bceSAndroid Build Coastguard Worker tcu::Vec4(float(x + 0) / float(GRID_SIZE) * 2.0f - 1.0f, float(y + 0) / float(GRID_SIZE) * 2.0f - 1.0f,
463*35238bceSAndroid Build Coastguard Worker 0.0f, 1.0f),
464*35238bceSAndroid Build Coastguard Worker tcu::Vec4(float(x + 0) / float(GRID_SIZE) * 2.0f - 1.0f, float(y + 1) / float(GRID_SIZE) * 2.0f - 1.0f,
465*35238bceSAndroid Build Coastguard Worker 0.0f, 1.0f),
466*35238bceSAndroid Build Coastguard Worker tcu::Vec4(float(x + 1) / float(GRID_SIZE) * 2.0f - 1.0f, float(y + 1) / float(GRID_SIZE) * 2.0f - 1.0f,
467*35238bceSAndroid Build Coastguard Worker 0.0f, 1.0f),
468*35238bceSAndroid Build Coastguard Worker tcu::Vec4(float(x + 0) / float(GRID_SIZE) * 2.0f - 1.0f, float(y + 0) / float(GRID_SIZE) * 2.0f - 1.0f,
469*35238bceSAndroid Build Coastguard Worker 0.0f, 1.0f),
470*35238bceSAndroid Build Coastguard Worker tcu::Vec4(float(x + 1) / float(GRID_SIZE) * 2.0f - 1.0f, float(y + 1) / float(GRID_SIZE) * 2.0f - 1.0f,
471*35238bceSAndroid Build Coastguard Worker 0.0f, 1.0f),
472*35238bceSAndroid Build Coastguard Worker tcu::Vec4(float(x + 1) / float(GRID_SIZE) * 2.0f - 1.0f, float(y + 0) / float(GRID_SIZE) * 2.0f - 1.0f,
473*35238bceSAndroid Build Coastguard Worker 0.0f, 1.0f),
474*35238bceSAndroid Build Coastguard Worker };
475*35238bceSAndroid Build Coastguard Worker
476*35238bceSAndroid Build Coastguard Worker // copy cell vertices to the buffer.
477*35238bceSAndroid Build Coastguard Worker for (int v = 0; v < 6; ++v)
478*35238bceSAndroid Build Coastguard Worker memcpy(&dataBuf[m_spec.bufferOffset + m_spec.positionAttrOffset +
479*35238bceSAndroid Build Coastguard Worker m_spec.bufferStride * ((y * GRID_SIZE + x) * 6 + v)],
480*35238bceSAndroid Build Coastguard Worker positions[v].getPtr(), sizeof(positions[v]));
481*35238bceSAndroid Build Coastguard Worker
482*35238bceSAndroid Build Coastguard Worker // copy color to buffer
483*35238bceSAndroid Build Coastguard Worker if (m_spec.hasColorAttr)
484*35238bceSAndroid Build Coastguard Worker for (int v = 0; v < 6; ++v)
485*35238bceSAndroid Build Coastguard Worker memcpy(&dataBuf[m_spec.bufferOffset + m_spec.colorAttrOffset +
486*35238bceSAndroid Build Coastguard Worker m_spec.bufferStride * ((y * GRID_SIZE + x) * 6 + v)],
487*35238bceSAndroid Build Coastguard Worker color.getPtr(), sizeof(color));
488*35238bceSAndroid Build Coastguard Worker }
489*35238bceSAndroid Build Coastguard Worker
490*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &m_buf);
491*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, m_buf);
492*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)dataBuf.size(), &dataBuf[0], GL_STATIC_DRAW);
493*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, 0);
494*35238bceSAndroid Build Coastguard Worker
495*35238bceSAndroid Build Coastguard Worker if (gl.getError() != GL_NO_ERROR)
496*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not init buffer");
497*35238bceSAndroid Build Coastguard Worker }
498*35238bceSAndroid Build Coastguard Worker
createShader(void)499*35238bceSAndroid Build Coastguard Worker void SingleBindingCase::createShader(void)
500*35238bceSAndroid Build Coastguard Worker {
501*35238bceSAndroid Build Coastguard Worker m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
502*35238bceSAndroid Build Coastguard Worker << glu::VertexSource(genVertexSource())
503*35238bceSAndroid Build Coastguard Worker << glu::FragmentSource(s_colorFragmentShader));
504*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_program;
505*35238bceSAndroid Build Coastguard Worker
506*35238bceSAndroid Build Coastguard Worker if (!m_program->isOk())
507*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build shader");
508*35238bceSAndroid Build Coastguard Worker }
509*35238bceSAndroid Build Coastguard Worker
genVertexSource(void)510*35238bceSAndroid Build Coastguard Worker std::string SingleBindingCase::genVertexSource(void)
511*35238bceSAndroid Build Coastguard Worker {
512*35238bceSAndroid Build Coastguard Worker const bool useUniformColor = !m_spec.hasColorAttr;
513*35238bceSAndroid Build Coastguard Worker std::ostringstream buf;
514*35238bceSAndroid Build Coastguard Worker
515*35238bceSAndroid Build Coastguard Worker buf << "#version 310 es\n"
516*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_position;\n";
517*35238bceSAndroid Build Coastguard Worker
518*35238bceSAndroid Build Coastguard Worker if (!useUniformColor)
519*35238bceSAndroid Build Coastguard Worker buf << "in highp vec4 a_color;\n";
520*35238bceSAndroid Build Coastguard Worker else
521*35238bceSAndroid Build Coastguard Worker buf << "uniform highp vec4 u_color;\n";
522*35238bceSAndroid Build Coastguard Worker
523*35238bceSAndroid Build Coastguard Worker buf << "out highp vec4 v_color;\n"
524*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
525*35238bceSAndroid Build Coastguard Worker "{\n"
526*35238bceSAndroid Build Coastguard Worker " gl_Position = a_position;\n"
527*35238bceSAndroid Build Coastguard Worker " v_color = "
528*35238bceSAndroid Build Coastguard Worker << ((useUniformColor) ? ("u_color") : ("a_color"))
529*35238bceSAndroid Build Coastguard Worker << ";\n"
530*35238bceSAndroid Build Coastguard Worker "}\n";
531*35238bceSAndroid Build Coastguard Worker
532*35238bceSAndroid Build Coastguard Worker return buf.str();
533*35238bceSAndroid Build Coastguard Worker }
534*35238bceSAndroid Build Coastguard Worker
535*35238bceSAndroid Build Coastguard Worker class BindVertexBufferCase : public TestCase
536*35238bceSAndroid Build Coastguard Worker {
537*35238bceSAndroid Build Coastguard Worker public:
538*35238bceSAndroid Build Coastguard Worker BindVertexBufferCase(Context &ctx, const char *name, const char *desc, int offset, int drawCount);
539*35238bceSAndroid Build Coastguard Worker ~BindVertexBufferCase(void);
540*35238bceSAndroid Build Coastguard Worker
541*35238bceSAndroid Build Coastguard Worker void init(void);
542*35238bceSAndroid Build Coastguard Worker void deinit(void);
543*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
544*35238bceSAndroid Build Coastguard Worker
545*35238bceSAndroid Build Coastguard Worker private:
546*35238bceSAndroid Build Coastguard Worker const int m_offset;
547*35238bceSAndroid Build Coastguard Worker const int m_drawCount;
548*35238bceSAndroid Build Coastguard Worker uint32_t m_buffer;
549*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_program;
550*35238bceSAndroid Build Coastguard Worker };
551*35238bceSAndroid Build Coastguard Worker
BindVertexBufferCase(Context & ctx,const char * name,const char * desc,int offset,int drawCount)552*35238bceSAndroid Build Coastguard Worker BindVertexBufferCase::BindVertexBufferCase(Context &ctx, const char *name, const char *desc, int offset, int drawCount)
553*35238bceSAndroid Build Coastguard Worker : TestCase(ctx, name, desc)
554*35238bceSAndroid Build Coastguard Worker , m_offset(offset)
555*35238bceSAndroid Build Coastguard Worker , m_drawCount(drawCount)
556*35238bceSAndroid Build Coastguard Worker , m_buffer(0)
557*35238bceSAndroid Build Coastguard Worker , m_program(DE_NULL)
558*35238bceSAndroid Build Coastguard Worker {
559*35238bceSAndroid Build Coastguard Worker }
560*35238bceSAndroid Build Coastguard Worker
~BindVertexBufferCase(void)561*35238bceSAndroid Build Coastguard Worker BindVertexBufferCase::~BindVertexBufferCase(void)
562*35238bceSAndroid Build Coastguard Worker {
563*35238bceSAndroid Build Coastguard Worker deinit();
564*35238bceSAndroid Build Coastguard Worker }
565*35238bceSAndroid Build Coastguard Worker
init(void)566*35238bceSAndroid Build Coastguard Worker void BindVertexBufferCase::init(void)
567*35238bceSAndroid Build Coastguard Worker {
568*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
569*35238bceSAndroid Build Coastguard Worker std::vector<tcu::Vec4> data(m_drawCount); // !< some junk data to make sure buffer is really allocated
570*35238bceSAndroid Build Coastguard Worker
571*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &m_buffer);
572*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer);
573*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ARRAY_BUFFER, int(m_drawCount * sizeof(tcu::Vec4)), &data[0], GL_STATIC_DRAW);
574*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "buffer gen");
575*35238bceSAndroid Build Coastguard Worker
576*35238bceSAndroid Build Coastguard Worker m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
577*35238bceSAndroid Build Coastguard Worker << glu::VertexSource(s_vertexSource)
578*35238bceSAndroid Build Coastguard Worker << glu::FragmentSource(s_fragmentSource));
579*35238bceSAndroid Build Coastguard Worker if (!m_program->isOk())
580*35238bceSAndroid Build Coastguard Worker {
581*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << *m_program;
582*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("could not build program");
583*35238bceSAndroid Build Coastguard Worker }
584*35238bceSAndroid Build Coastguard Worker }
585*35238bceSAndroid Build Coastguard Worker
deinit(void)586*35238bceSAndroid Build Coastguard Worker void BindVertexBufferCase::deinit(void)
587*35238bceSAndroid Build Coastguard Worker {
588*35238bceSAndroid Build Coastguard Worker if (m_buffer)
589*35238bceSAndroid Build Coastguard Worker {
590*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffer);
591*35238bceSAndroid Build Coastguard Worker m_buffer = 0;
592*35238bceSAndroid Build Coastguard Worker }
593*35238bceSAndroid Build Coastguard Worker
594*35238bceSAndroid Build Coastguard Worker delete m_program;
595*35238bceSAndroid Build Coastguard Worker m_program = DE_NULL;
596*35238bceSAndroid Build Coastguard Worker }
597*35238bceSAndroid Build Coastguard Worker
iterate(void)598*35238bceSAndroid Build Coastguard Worker BindVertexBufferCase::IterateResult BindVertexBufferCase::iterate(void)
599*35238bceSAndroid Build Coastguard Worker {
600*35238bceSAndroid Build Coastguard Worker glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
601*35238bceSAndroid Build Coastguard Worker const int32_t positionLoc = gl.glGetAttribLocation(m_program->getProgram(), "a_position");
602*35238bceSAndroid Build Coastguard Worker tcu::Surface dst(m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight());
603*35238bceSAndroid Build Coastguard Worker glu::VertexArray vao(m_context.getRenderContext());
604*35238bceSAndroid Build Coastguard Worker
605*35238bceSAndroid Build Coastguard Worker gl.enableLogging(true);
606*35238bceSAndroid Build Coastguard Worker
607*35238bceSAndroid Build Coastguard Worker gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
608*35238bceSAndroid Build Coastguard Worker gl.glClear(GL_COLOR_BUFFER_BIT);
609*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup");
610*35238bceSAndroid Build Coastguard Worker
611*35238bceSAndroid Build Coastguard Worker gl.glUseProgram(m_program->getProgram());
612*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.glGetError(), "use program");
613*35238bceSAndroid Build Coastguard Worker
614*35238bceSAndroid Build Coastguard Worker gl.glBindVertexArray(*vao);
615*35238bceSAndroid Build Coastguard Worker gl.glEnableVertexAttribArray(positionLoc);
616*35238bceSAndroid Build Coastguard Worker gl.glVertexAttribFormat(positionLoc, 4, GL_FLOAT, GL_FALSE, 0);
617*35238bceSAndroid Build Coastguard Worker gl.glVertexAttribBinding(positionLoc, 0);
618*35238bceSAndroid Build Coastguard Worker gl.glBindVertexBuffer(0, m_buffer, m_offset, int(sizeof(tcu::Vec4)));
619*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.glGetError(), "set buffer");
620*35238bceSAndroid Build Coastguard Worker
621*35238bceSAndroid Build Coastguard Worker gl.glDrawArrays(GL_POINTS, 0, m_drawCount);
622*35238bceSAndroid Build Coastguard Worker
623*35238bceSAndroid Build Coastguard Worker // allow errors after attempted out-of-bounds memory access
624*35238bceSAndroid Build Coastguard Worker {
625*35238bceSAndroid Build Coastguard Worker const uint32_t error = gl.glGetError();
626*35238bceSAndroid Build Coastguard Worker
627*35238bceSAndroid Build Coastguard Worker if (error != GL_NO_ERROR)
628*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Got error: " << glu::getErrorStr(error) << ", ignoring..."
629*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
630*35238bceSAndroid Build Coastguard Worker }
631*35238bceSAndroid Build Coastguard Worker
632*35238bceSAndroid Build Coastguard Worker // read pixels to wait for rendering
633*35238bceSAndroid Build Coastguard Worker gl.glFinish();
634*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
635*35238bceSAndroid Build Coastguard Worker
636*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
637*35238bceSAndroid Build Coastguard Worker return STOP;
638*35238bceSAndroid Build Coastguard Worker }
639*35238bceSAndroid Build Coastguard Worker
640*35238bceSAndroid Build Coastguard Worker } // namespace
641*35238bceSAndroid Build Coastguard Worker
VertexAttributeBindingTests(Context & context)642*35238bceSAndroid Build Coastguard Worker VertexAttributeBindingTests::VertexAttributeBindingTests(Context &context)
643*35238bceSAndroid Build Coastguard Worker : TestCaseGroup(context, "vertex_attribute_binding", "Test vertex attribute binding stress tests")
644*35238bceSAndroid Build Coastguard Worker {
645*35238bceSAndroid Build Coastguard Worker }
646*35238bceSAndroid Build Coastguard Worker
~VertexAttributeBindingTests(void)647*35238bceSAndroid Build Coastguard Worker VertexAttributeBindingTests::~VertexAttributeBindingTests(void)
648*35238bceSAndroid Build Coastguard Worker {
649*35238bceSAndroid Build Coastguard Worker }
650*35238bceSAndroid Build Coastguard Worker
init(void)651*35238bceSAndroid Build Coastguard Worker void VertexAttributeBindingTests::init(void)
652*35238bceSAndroid Build Coastguard Worker {
653*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const unalignedGroup = new tcu::TestCaseGroup(m_testCtx, "unaligned", "Unaligned access");
654*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const bufferRangeGroup =
655*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "buffer_bounds", "Source data over buffer bounds");
656*35238bceSAndroid Build Coastguard Worker
657*35238bceSAndroid Build Coastguard Worker addChild(unalignedGroup);
658*35238bceSAndroid Build Coastguard Worker addChild(bufferRangeGroup);
659*35238bceSAndroid Build Coastguard Worker
660*35238bceSAndroid Build Coastguard Worker // .unaligned
661*35238bceSAndroid Build Coastguard Worker {
662*35238bceSAndroid Build Coastguard Worker unalignedGroup->addChild(
663*35238bceSAndroid Build Coastguard Worker new SingleBindingCase(m_context, "elements_1_unaligned", SingleBindingCase::FLAG_ATTRIB_UNALIGNED));
664*35238bceSAndroid Build Coastguard Worker unalignedGroup->addChild(new SingleBindingCase(m_context, "offset_elements_1_unaligned",
665*35238bceSAndroid Build Coastguard Worker SingleBindingCase::FLAG_BUF_ALIGNED_OFFSET |
666*35238bceSAndroid Build Coastguard Worker SingleBindingCase::FLAG_ATTRIB_UNALIGNED));
667*35238bceSAndroid Build Coastguard Worker
668*35238bceSAndroid Build Coastguard Worker unalignedGroup->addChild(new SingleBindingCase(m_context, "unaligned_offset_elements_1",
669*35238bceSAndroid Build Coastguard Worker SingleBindingCase::FLAG_BUF_UNALIGNED_OFFSET | 0));
670*35238bceSAndroid Build Coastguard Worker unalignedGroup->addChild(new SingleBindingCase(m_context, "unaligned_offset_elements_1_unaligned",
671*35238bceSAndroid Build Coastguard Worker SingleBindingCase::FLAG_BUF_UNALIGNED_OFFSET |
672*35238bceSAndroid Build Coastguard Worker SingleBindingCase::FLAG_ATTRIB_UNALIGNED));
673*35238bceSAndroid Build Coastguard Worker unalignedGroup->addChild(new SingleBindingCase(m_context, "unaligned_offset_elements_2",
674*35238bceSAndroid Build Coastguard Worker SingleBindingCase::FLAG_BUF_UNALIGNED_OFFSET |
675*35238bceSAndroid Build Coastguard Worker SingleBindingCase::FLAG_ATTRIBS_MULTIPLE_ELEMS));
676*35238bceSAndroid Build Coastguard Worker unalignedGroup->addChild(new SingleBindingCase(m_context, "unaligned_offset_elements_2_share_elements",
677*35238bceSAndroid Build Coastguard Worker SingleBindingCase::FLAG_BUF_UNALIGNED_OFFSET |
678*35238bceSAndroid Build Coastguard Worker SingleBindingCase::FLAG_ATTRIBS_SHARED_ELEMS));
679*35238bceSAndroid Build Coastguard Worker
680*35238bceSAndroid Build Coastguard Worker unalignedGroup->addChild(new SingleBindingCase(m_context, "unaligned_stride_elements_1",
681*35238bceSAndroid Build Coastguard Worker SingleBindingCase::FLAG_BUF_UNALIGNED_STRIDE | 0));
682*35238bceSAndroid Build Coastguard Worker unalignedGroup->addChild(new SingleBindingCase(m_context, "unaligned_stride_elements_2",
683*35238bceSAndroid Build Coastguard Worker SingleBindingCase::FLAG_BUF_UNALIGNED_STRIDE |
684*35238bceSAndroid Build Coastguard Worker SingleBindingCase::FLAG_ATTRIBS_MULTIPLE_ELEMS));
685*35238bceSAndroid Build Coastguard Worker unalignedGroup->addChild(new SingleBindingCase(m_context, "unaligned_stride_elements_2_share_elements",
686*35238bceSAndroid Build Coastguard Worker SingleBindingCase::FLAG_BUF_UNALIGNED_STRIDE |
687*35238bceSAndroid Build Coastguard Worker SingleBindingCase::FLAG_ATTRIBS_SHARED_ELEMS));
688*35238bceSAndroid Build Coastguard Worker }
689*35238bceSAndroid Build Coastguard Worker
690*35238bceSAndroid Build Coastguard Worker // .buffer_bounds
691*35238bceSAndroid Build Coastguard Worker {
692*35238bceSAndroid Build Coastguard Worker // bind buffer offset cases
693*35238bceSAndroid Build Coastguard Worker bufferRangeGroup->addChild(new BindVertexBufferCase(m_context, "bind_vertex_buffer_offset_over_bounds_10",
694*35238bceSAndroid Build Coastguard Worker "Offset over buffer bounds", 0x00210000, 10));
695*35238bceSAndroid Build Coastguard Worker bufferRangeGroup->addChild(new BindVertexBufferCase(m_context, "bind_vertex_buffer_offset_over_bounds_1000",
696*35238bceSAndroid Build Coastguard Worker "Offset over buffer bounds", 0x00210000, 1000));
697*35238bceSAndroid Build Coastguard Worker bufferRangeGroup->addChild(new BindVertexBufferCase(m_context, "bind_vertex_buffer_offset_near_wrap_10",
698*35238bceSAndroid Build Coastguard Worker "Offset over buffer bounds, near wrapping", 0x7FFFFFF0,
699*35238bceSAndroid Build Coastguard Worker 10));
700*35238bceSAndroid Build Coastguard Worker bufferRangeGroup->addChild(new BindVertexBufferCase(m_context, "bind_vertex_buffer_offset_near_wrap_1000",
701*35238bceSAndroid Build Coastguard Worker "Offset over buffer bounds, near wrapping", 0x7FFFFFF0,
702*35238bceSAndroid Build Coastguard Worker 1000));
703*35238bceSAndroid Build Coastguard Worker }
704*35238bceSAndroid Build Coastguard Worker }
705*35238bceSAndroid Build Coastguard Worker
706*35238bceSAndroid Build Coastguard Worker } // namespace Stress
707*35238bceSAndroid Build Coastguard Worker } // namespace gles31
708*35238bceSAndroid Build Coastguard Worker } // namespace deqp
709