1/*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.0 Module
3 * -------------------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Buffer Object Query tests.
22 *//*--------------------------------------------------------------------*/
23
24#include "es2fBufferObjectQueryTests.hpp"
25#include "glsStateQueryUtil.hpp"
26#include "es2fApiCase.hpp"
27#include "gluRenderContext.hpp"
28#include "glwEnums.hpp"
29#include "glwFunctions.hpp"
30#include "deRandom.hpp"
31#include "deMath.h"
32
33#include <limits>
34
35using namespace glw; // GLint and other GL types
36using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
37
38
39namespace deqp
40{
41namespace gles2
42{
43namespace Functional
44{
45namespace BufferParamVerifiers
46{
47
48void checkIntEquals (tcu::TestContext& testCtx, GLint got, GLint expected)
49{
50	using tcu::TestLog;
51
52	if (got != expected)
53	{
54		testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage;
55		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
56			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
57	}
58}
59
60void checkPointerEquals (tcu::TestContext& testCtx, const void* got, const void* expected)
61{
62	using tcu::TestLog;
63
64	if (got != expected)
65	{
66		testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage;
67		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
68			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
69	}
70}
71
72class BufferParamVerifier : protected glu::CallLogWrapper
73{
74public:
75						BufferParamVerifier		(const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix);
76	virtual				~BufferParamVerifier	(); // make GCC happy
77
78	const char*			getTestNamePostfix		(void) const;
79
80	virtual void		verifyInteger			(tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference)	= DE_NULL;
81private:
82	const char*	const	m_testNamePostfix;
83};
84
85BufferParamVerifier::BufferParamVerifier (const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix)
86	: glu::CallLogWrapper	(gl, log)
87	, m_testNamePostfix		(testNamePostfix)
88{
89	enableLogging(true);
90}
91
92BufferParamVerifier::~BufferParamVerifier ()
93{
94}
95
96const char* BufferParamVerifier::getTestNamePostfix (void) const
97{
98	return m_testNamePostfix;
99}
100
101class GetBufferParameterIVerifier : public BufferParamVerifier
102{
103public:
104			GetBufferParameterIVerifier					(const glw::Functions& gl, tcu::TestLog& log);
105
106	void	verifyInteger								(tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference);
107};
108
109GetBufferParameterIVerifier::GetBufferParameterIVerifier (const glw::Functions& gl, tcu::TestLog& log)
110	: BufferParamVerifier(gl, log, "_getbufferparameteri")
111{
112}
113
114void GetBufferParameterIVerifier::verifyInteger (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference)
115{
116	using tcu::TestLog;
117
118	StateQueryMemoryWriteGuard<GLint> state;
119	glGetBufferParameteriv(target, name, &state);
120
121	if (!state.verifyValidity(testCtx))
122		return;
123
124	if (state != reference)
125	{
126		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage;
127
128		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
129			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid value");
130	}
131}
132
133} // BufferParamVerifiers
134
135namespace
136{
137
138using namespace BufferParamVerifiers;
139
140// Tests
141
142class BufferCase : public ApiCase
143{
144public:
145	BufferCase (Context& context, BufferParamVerifier* verifier, const char* name, const char* description)
146		: ApiCase			(context, name, description)
147		, m_bufferTarget	(0)
148		, m_verifier		(verifier)
149	{
150	}
151
152	virtual void testBuffer (void) = DE_NULL;
153
154	void test (void)
155	{
156		const GLenum bufferTargets[] =
157		{
158			GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER
159		};
160		const int targets = DE_LENGTH_OF_ARRAY(bufferTargets);
161
162		for (int ndx = 0; ndx < targets; ++ndx)
163		{
164			m_bufferTarget = bufferTargets[ndx];
165
166			GLuint bufferId = 0;
167			glGenBuffers(1, &bufferId);
168			glBindBuffer(m_bufferTarget, bufferId);
169			expectError(GL_NO_ERROR);
170
171			testBuffer();
172
173			glDeleteBuffers(1, &bufferId);
174			expectError(GL_NO_ERROR);
175		}
176	}
177
178protected:
179	GLenum					m_bufferTarget;
180	BufferParamVerifier*	m_verifier;
181};
182
183class BufferSizeCase : public BufferCase
184{
185public:
186	BufferSizeCase (Context& context, BufferParamVerifier* verifier, const char* name, const char* description)
187		: BufferCase(context, verifier, name, description)
188	{
189	}
190
191	void testBuffer (void)
192	{
193		const int numIteration = 16;
194		de::Random rnd(0xabcdef);
195
196		m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_SIZE, 0);
197
198		for (int i = 0; i < numIteration; ++i)
199		{
200			const GLint len = rnd.getInt(0, 1024);
201			glBufferData(m_bufferTarget, len, DE_NULL, GL_STREAM_DRAW);
202			expectError(GL_NO_ERROR);
203
204			m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_SIZE, len);
205			expectError(GL_NO_ERROR);
206		}
207	}
208};
209
210class BufferUsageCase : public BufferCase
211{
212public:
213	BufferUsageCase (Context& context, BufferParamVerifier* verifier, const char* name, const char* description)
214		: BufferCase(context, verifier, name, description)
215	{
216	}
217
218	void testBuffer (void)
219	{
220		const GLenum usages[] =
221		{
222			GL_STATIC_DRAW, GL_DYNAMIC_DRAW, GL_STREAM_DRAW
223		};
224
225		m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_USAGE, GL_STATIC_DRAW);
226
227		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(usages); ++ndx)
228		{
229			glBufferData(m_bufferTarget, 16, DE_NULL, usages[ndx]);
230			expectError(GL_NO_ERROR);
231
232			m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_USAGE, usages[ndx]);
233			expectError(GL_NO_ERROR);
234		}
235	}
236};
237
238} // anonymous
239
240#define FOR_EACH_VERIFIER(VERIFIERS, CODE_BLOCK)												\
241	for (int _verifierNdx = 0; _verifierNdx < DE_LENGTH_OF_ARRAY(VERIFIERS); _verifierNdx++)	\
242	{																							\
243		BufferParamVerifier* verifier = (VERIFIERS)[_verifierNdx];								\
244		CODE_BLOCK;																				\
245	}
246
247BufferObjectQueryTests::BufferObjectQueryTests (Context& context)
248	: TestCaseGroup		(context, "buffer_object", "Buffer Object Query tests")
249	, m_verifierInt		(DE_NULL)
250{
251}
252
253BufferObjectQueryTests::~BufferObjectQueryTests (void)
254{
255	deinit();
256}
257
258void BufferObjectQueryTests::init (void)
259{
260	using namespace BufferParamVerifiers;
261
262	DE_ASSERT(m_verifierInt == DE_NULL);
263
264	m_verifierInt		= new GetBufferParameterIVerifier	(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
265	BufferParamVerifier* verifiers[] = {m_verifierInt};
266
267	FOR_EACH_VERIFIER(verifiers, addChild(new BufferSizeCase		(m_context, verifier,	(std::string("buffer_size")				+ verifier->getTestNamePostfix()).c_str(), "BUFFER_SIZE")));
268	FOR_EACH_VERIFIER(verifiers, addChild(new BufferUsageCase		(m_context, verifier,	(std::string("buffer_usage")			+ verifier->getTestNamePostfix()).c_str(), "BUFFER_USAGE")));
269}
270
271void BufferObjectQueryTests::deinit (void)
272{
273	if (m_verifierInt)
274	{
275		delete m_verifierInt;
276		m_verifierInt = NULL;
277	}
278
279	this->TestCaseGroup::deinit();
280}
281
282} // Functional
283} // gles2
284} // deqp
285