glsStateQueryUtil.hpp revision 591173f18359cabb0d9d88adf3eeb381a21ffc04
1#ifndef _GLSSTATEQUERYUTIL_HPP
2#define _GLSSTATEQUERYUTIL_HPP
3/*-------------------------------------------------------------------------
4 * drawElements Quality Program OpenGL (ES) Module
5 * -----------------------------------------------
6 *
7 * Copyright 2014 The Android Open Source Project
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief State Query test utils.
24 *//*--------------------------------------------------------------------*/
25
26#include "tcuDefs.hpp"
27#include "tcuTestLog.hpp"
28#include "tcuTestContext.hpp"
29#include "tcuResultCollector.hpp"
30#include "glwDefs.hpp"
31#include "deMath.h"
32
33namespace glu
34{
35class CallLogWrapper;
36} // glu
37
38namespace deqp
39{
40namespace gls
41{
42namespace StateQueryUtil
43{
44
45#define GLS_COLLECT_GL_ERROR(RES, ERR, MSG) \
46	do \
47	{ \
48		const deUint32 err = (ERR); \
49		if (err != GL_NO_ERROR) \
50			(RES).fail(std::string("Got Error ") + glu::getErrorStr(err).toString() + ": " + (MSG)); \
51	} \
52	while (deGetFalse())
53
54/*--------------------------------------------------------------------*//*!
55 * \brief Rounds given float to the nearest integer (half up).
56 *
57 * Returns the nearest integer for a float argument. In the case that there
58 * are two nearest integers at the equal distance (aka. the argument is of
59 * form x.5), the integer with the higher value is chosen. (x.5 rounds to x+1)
60 *//*--------------------------------------------------------------------*/
61template <typename T>
62T roundGLfloatToNearestIntegerHalfUp (float val)
63{
64	return (T)(deFloatFloor(val + 0.5f));
65}
66
67/*--------------------------------------------------------------------*//*!
68 * \brief Rounds given float to the nearest integer (half down).
69 *
70 * Returns the nearest integer for a float argument. In the case that there
71 * are two nearest integers at the equal distance (aka. the argument is of
72 * form x.5), the integer with the higher value is chosen. (x.5 rounds to x)
73 *//*--------------------------------------------------------------------*/
74template <typename T>
75T roundGLfloatToNearestIntegerHalfDown (float val)
76{
77	return (T)(deFloatCeil(val - 0.5f));
78}
79
80template <typename T>
81class StateQueryMemoryWriteGuard
82{
83public:
84					StateQueryMemoryWriteGuard	(void);
85
86					operator T&					(void);
87	T*				operator &					(void);
88
89	bool			isUndefined					(void) const;
90	bool			isMemoryContaminated		(void) const;
91	bool			isPreguardContaminated		(void) const;
92	bool			isPostguardContaminated		(void) const;
93	bool			verifyValidity				(tcu::TestContext& testCtx) const;
94	bool			verifyValidity				(tcu::ResultCollector& result) const;
95
96	const T&		get							(void) const { return m_value; }
97
98private:
99	enum
100	{
101		WRITE_GUARD_VALUE = 0xDE
102	};
103
104	T				m_preguard;
105	T				m_value;
106	T				m_postguard; // \note guards are not const qualified since the GL implementation might modify them
107};
108
109template <typename T>
110StateQueryMemoryWriteGuard<T>::StateQueryMemoryWriteGuard (void)
111{
112	DE_STATIC_ASSERT(sizeof(T) * 3 == sizeof(StateQueryMemoryWriteGuard<T>)); // tightly packed
113
114	for (size_t i = 0; i < sizeof(T); ++i)
115	{
116		((deUint8*)&m_preguard)[i]	= (deUint8)WRITE_GUARD_VALUE;
117		((deUint8*)&m_value)[i]		= (deUint8)WRITE_GUARD_VALUE;
118		((deUint8*)&m_postguard)[i]	= (deUint8)WRITE_GUARD_VALUE;
119	}
120}
121
122template <typename T>
123StateQueryMemoryWriteGuard<T>::operator T& (void)
124{
125	return m_value;
126}
127
128template <typename T>
129T* StateQueryMemoryWriteGuard<T>::operator & (void)
130{
131	return &m_value;
132}
133
134template <typename T>
135bool StateQueryMemoryWriteGuard<T>::isUndefined () const
136{
137	for (size_t i = 0; i < sizeof(T); ++i)
138		if (((deUint8*)&m_value)[i] != (deUint8)WRITE_GUARD_VALUE)
139			return false;
140	return true;
141}
142
143template <typename T>
144bool StateQueryMemoryWriteGuard<T>::isMemoryContaminated () const
145{
146	return isPreguardContaminated() || isPostguardContaminated();
147}
148
149template <typename T>
150bool StateQueryMemoryWriteGuard<T>::isPreguardContaminated (void) const
151{
152	for (size_t i = 0; i < sizeof(T); ++i)
153		if (((deUint8*)&m_preguard)[i] != (deUint8)WRITE_GUARD_VALUE)
154			return true;
155	return false;
156}
157
158template <typename T>
159bool StateQueryMemoryWriteGuard<T>::isPostguardContaminated (void) const
160{
161	for (size_t i = 0; i < sizeof(T); ++i)
162		if (((deUint8*)&m_postguard)[i] != (deUint8)WRITE_GUARD_VALUE)
163			return true;
164	return false;
165}
166
167template <typename T>
168bool StateQueryMemoryWriteGuard<T>::verifyValidity (tcu::TestContext& testCtx) const
169{
170	using tcu::TestLog;
171
172	if (isPreguardContaminated())
173	{
174		testCtx.getLog() << TestLog::Message << "// ERROR: Pre-guard value was modified " << TestLog::EndMessage;
175		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS ||
176			testCtx.getTestResult() == QP_TEST_RESULT_LAST)
177			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Get* did an illegal memory write");
178
179		return false;
180	}
181	else if (isPostguardContaminated())
182	{
183		testCtx.getLog() << TestLog::Message << "// ERROR: Post-guard value was modified " << TestLog::EndMessage;
184		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS ||
185			testCtx.getTestResult() == QP_TEST_RESULT_LAST)
186			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Get* did an illegal memory write");
187
188		return false;
189	}
190	else if (isUndefined())
191	{
192		testCtx.getLog() << TestLog::Message << "// ERROR: Get* did not return a value" << TestLog::EndMessage;
193		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS ||
194			testCtx.getTestResult() == QP_TEST_RESULT_LAST)
195			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Get* did not return a value");
196
197		return false;
198	}
199
200	return true;
201}
202
203template <typename T>
204bool StateQueryMemoryWriteGuard<T>::verifyValidity (tcu::ResultCollector& result) const
205{
206	using tcu::TestLog;
207
208	if (isPreguardContaminated())
209	{
210		result.fail("pre-guard value was modified");
211		return false;
212	}
213	else if (isPostguardContaminated())
214	{
215		result.fail("post-guard value was modified");
216		return false;
217	}
218	else if (isUndefined())
219	{
220		result.fail("Get* did not return a value");
221		return false;
222	}
223
224	return true;
225}
226
227template<typename T>
228std::ostream& operator<< (std::ostream& str, const StateQueryMemoryWriteGuard<T>& guard)
229{
230	return str << guard.get();
231}
232
233// Verifiers
234
235enum QueryType
236{
237	QUERY_BOOLEAN = 0,
238	QUERY_BOOLEAN_VEC4,
239	QUERY_ISENABLED,
240	QUERY_INTEGER,
241	QUERY_INTEGER64,
242	QUERY_FLOAT,
243
244	// indexed
245	QUERY_INDEXED_BOOLEAN,
246	QUERY_INDEXED_BOOLEAN_VEC4,
247	QUERY_INDEXED_ISENABLED,
248	QUERY_INDEXED_INTEGER,
249	QUERY_INDEXED_INTEGER_VEC4,
250	QUERY_INDEXED_INTEGER64,
251	QUERY_INDEXED_INTEGER64_VEC4,
252
253	// attributes
254	QUERY_ATTRIBUTE_INTEGER,
255	QUERY_ATTRIBUTE_FLOAT,
256	QUERY_ATTRIBUTE_PURE_INTEGER,
257	QUERY_ATTRIBUTE_PURE_UNSIGNED_INTEGER,
258
259	// fb
260	QUERY_FRAMEBUFFER_INTEGER,
261
262	// program
263	QUERY_PROGRAM_INTEGER,
264	QUERY_PROGRAM_INTEGER_VEC3,
265
266	// program pipeline
267	QUERY_PIPELINE_INTEGER,
268
269	// texture param
270	QUERY_TEXTURE_PARAM_INTEGER,
271	QUERY_TEXTURE_PARAM_FLOAT,
272	QUERY_TEXTURE_PARAM_PURE_INTEGER,
273	QUERY_TEXTURE_PARAM_PURE_UNSIGNED_INTEGER,
274	QUERY_TEXTURE_PARAM_INTEGER_VEC4,
275	QUERY_TEXTURE_PARAM_FLOAT_VEC4,
276	QUERY_TEXTURE_PARAM_PURE_INTEGER_VEC4,
277	QUERY_TEXTURE_PARAM_PURE_UNSIGNED_INTEGER_VEC4,
278
279	// texture level
280	QUERY_TEXTURE_LEVEL_INTEGER,
281	QUERY_TEXTURE_LEVEL_FLOAT,
282
283	// pointer
284	QUERY_POINTER,
285
286	// object states
287	QUERY_ISTEXTURE,
288
289	// query queries
290	QUERY_QUERY,
291
292	// sampler state
293	QUERY_SAMPLER_PARAM_INTEGER,
294	QUERY_SAMPLER_PARAM_FLOAT,
295	QUERY_SAMPLER_PARAM_PURE_INTEGER,
296	QUERY_SAMPLER_PARAM_PURE_UNSIGNED_INTEGER,
297	QUERY_SAMPLER_PARAM_INTEGER_VEC4,
298	QUERY_SAMPLER_PARAM_FLOAT_VEC4,
299	QUERY_SAMPLER_PARAM_PURE_INTEGER_VEC4,
300	QUERY_SAMPLER_PARAM_PURE_UNSIGNED_INTEGER_VEC4,
301
302	QUERY_LAST
303};
304
305enum DataType
306{
307	DATATYPE_BOOLEAN = 0,
308	DATATYPE_INTEGER,
309	DATATYPE_INTEGER64,
310	DATATYPE_FLOAT,
311	DATATYPE_UNSIGNED_INTEGER,
312	DATATYPE_INTEGER_VEC3,
313	DATATYPE_FLOAT_VEC4,
314	DATATYPE_INTEGER_VEC4,
315	DATATYPE_INTEGER64_VEC4,
316	DATATYPE_UNSIGNED_INTEGER_VEC4,
317	DATATYPE_BOOLEAN_VEC4,
318	DATATYPE_POINTER,
319
320	DATATYPE_LAST
321};
322
323class QueriedState
324{
325public:
326	typedef glw::GLint		GLIntVec3[3];
327	typedef glw::GLint		GLIntVec4[4];
328	typedef glw::GLuint		GLUintVec4[4];
329	typedef glw::GLfloat	GLFloatVec4[4];
330	typedef bool			BooleanVec4[4];
331	typedef glw::GLint64	GLInt64Vec4[4];
332
333							QueriedState			(void);
334	explicit				QueriedState			(glw::GLint);
335	explicit				QueriedState			(glw::GLint64);
336	explicit				QueriedState			(bool);
337	explicit				QueriedState			(glw::GLfloat);
338	explicit				QueriedState			(glw::GLuint);
339	explicit				QueriedState			(const GLIntVec3&);
340	explicit				QueriedState			(void*);
341	explicit				QueriedState			(const GLIntVec4&);
342	explicit				QueriedState			(const GLUintVec4&);
343	explicit				QueriedState			(const GLFloatVec4&);
344	explicit				QueriedState			(const BooleanVec4&);
345	explicit				QueriedState			(const GLInt64Vec4&);
346
347	bool					isUndefined				(void) const;
348	DataType				getType					(void) const;
349
350	glw::GLint&				getIntAccess			(void);
351	glw::GLint64&			getInt64Access			(void);
352	bool&					getBoolAccess			(void);
353	glw::GLfloat&			getFloatAccess			(void);
354	glw::GLuint&			getUintAccess			(void);
355	GLIntVec3&				getIntVec3Access		(void);
356	void*&					getPtrAccess			(void);
357	GLIntVec4&				getIntVec4Access		(void);
358	GLUintVec4&				getUintVec4Access		(void);
359	GLFloatVec4&			getFloatVec4Access		(void);
360	BooleanVec4&			getBooleanVec4Access	(void);
361	GLInt64Vec4&			getInt64Vec4Access		(void);
362
363private:
364	DataType				m_type;
365	union
366	{
367		glw::GLint			vInt;
368		glw::GLint64		vInt64;
369		bool				vBool;
370		glw::GLfloat		vFloat;
371		glw::GLuint			vUint;
372		GLIntVec3			vIntVec3;
373		void*				vPtr;
374		GLIntVec4			vIntVec4;
375		GLUintVec4			vUintVec4;
376		GLFloatVec4			vFloatVec4;
377		BooleanVec4			vBooleanVec4;
378		GLInt64Vec4			vInt64Vec4;
379	} m_v;
380};
381
382// query functions
383
384void queryState									(tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum pname, QueriedState& state);
385void queryIndexedState							(tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int index, QueriedState& state);
386void queryAttributeState						(tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int index, QueriedState& state);
387void queryFramebufferState						(tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state);
388void queryProgramState							(tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint program, glw::GLenum pname, QueriedState& state);
389void queryPipelineState							(tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint pipeline, glw::GLenum pname, QueriedState& state);
390void queryTextureParamState						(tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state);
391void queryTextureLevelState						(tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int level, glw::GLenum pname, QueriedState& state);
392void queryPointerState							(tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum pname, QueriedState& state);
393void queryObjectState							(tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint handle, QueriedState& state);
394void queryQueryState							(tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state);
395void querySamplerState							(tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint sampler, glw::GLenum pname, QueriedState& state);
396
397// verification functions
398
399void verifyBoolean								(tcu::ResultCollector& result, QueriedState& state, bool expected);
400void verifyInteger								(tcu::ResultCollector& result, QueriedState& state, int expected);
401void verifyIntegerMin							(tcu::ResultCollector& result, QueriedState& state, int minValue);
402void verifyIntegerMax							(tcu::ResultCollector& result, QueriedState& state, int maxValue);
403void verifyIntegersEqual						(tcu::ResultCollector& result, QueriedState& stateA, QueriedState& stateB);
404void verifyFloat								(tcu::ResultCollector& result, QueriedState& state, float expected);
405void verifyFloatMin								(tcu::ResultCollector& result, QueriedState& state, float minValue);
406void verifyFloatMax								(tcu::ResultCollector& result, QueriedState& state, float maxValue);
407void verifyIntegerVec3							(tcu::ResultCollector& result, QueriedState& state, const tcu::IVec3& expected);
408void verifyIntegerVec4							(tcu::ResultCollector& result, QueriedState& state, const tcu::IVec4& expected);
409void verifyUnsignedIntegerVec4					(tcu::ResultCollector& result, QueriedState& state, const tcu::UVec4& expected);
410void verifyFloatVec4							(tcu::ResultCollector& result, QueriedState& state, const tcu::Vec4& expected);
411void verifyBooleanVec4							(tcu::ResultCollector& result, QueriedState& state, const tcu::BVec4& expected);
412void verifyPointer								(tcu::ResultCollector& result, QueriedState& state, const void* expected);
413void verifyNormalizedI32Vec4					(tcu::ResultCollector& result, QueriedState& state, const tcu::IVec4& expected);
414
415// Helper functions that both query and verify
416
417void verifyStateBoolean							(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		bool expected,			QueryType type);
418void verifyStateInteger							(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		int expected,			QueryType type);
419void verifyStateIntegerMin						(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		int minValue,			QueryType type);
420void verifyStateIntegerMax						(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		int maxValue,			QueryType type);
421void verifyStateIntegerEqualToOther				(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		glw::GLenum other,		QueryType type);
422void verifyStateFloat							(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		float reference,		QueryType type);
423void verifyStateFloatMin						(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		float minValue,			QueryType type);
424void verifyStateFloatMax						(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		float maxValue,			QueryType type);
425void verifyStatePointer							(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		const void* expected,	QueryType type);
426void verifyStateIndexedBoolean					(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		int index,				bool expected,				QueryType type);
427void verifyStateIndexedBooleanVec4				(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		int index,				const tcu::BVec4& expected,	QueryType type);
428void verifyStateIndexedInteger					(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		int index,				int expected,				QueryType type);
429void verifyStateIndexedIntegerMin				(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		int index,				int minValue,				QueryType type);
430void verifyStateAttributeInteger				(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		int index,				int expected,				QueryType type);
431void verifyStateFramebufferInteger				(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		glw::GLenum pname,		int expected,				QueryType type);
432void verifyStateFramebufferIntegerMin			(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		glw::GLenum pname,		int minValue,				QueryType type);
433void verifyStateProgramInteger					(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint program,	glw::GLenum pname,		int expected,				QueryType type);
434void verifyStateProgramIntegerVec3				(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint program, 	glw::GLenum pname,		const tcu::IVec3& expected,	QueryType type);
435void verifyStatePipelineInteger					(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint pipeline,	glw::GLenum pname,		int expected,				QueryType type);
436void verifyStateTextureParamInteger				(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		glw::GLenum pname,		int expected,				QueryType type);
437void verifyStateTextureParamFloat				(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		glw::GLenum pname,		float expected,				QueryType type);
438void verifyStateTextureParamFloatVec4			(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		glw::GLenum pname,		const tcu::Vec4& expected,	QueryType type);
439void verifyStateTextureParamNormalizedI32Vec4	(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		glw::GLenum pname,		const tcu::IVec4& expected,	QueryType type);
440void verifyStateTextureParamIntegerVec4			(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		glw::GLenum pname,		const tcu::IVec4& expected,	QueryType type);
441void verifyStateTextureParamUnsignedIntegerVec4	(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		glw::GLenum pname,		const tcu::UVec4& expected,	QueryType type);
442void verifyStateTextureLevelInteger				(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		int level,				glw::GLenum pname,			int expected,		QueryType type);
443void verifyStateObjectBoolean					(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint handle,		bool expected,			QueryType type);
444void verifyStateQueryInteger					(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target,		glw::GLenum pname,		int expected,				QueryType type);
445void verifyStateSamplerParamInteger				(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler,	glw::GLenum pname,		int expected,				QueryType type);
446void verifyStateSamplerParamFloat				(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler,	glw::GLenum pname,		float expected,				QueryType type);
447void verifyStateSamplerParamFloatVec4			(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler,	glw::GLenum pname,		const tcu::Vec4& expected,	QueryType type);
448void verifyStateSamplerParamNormalizedI32Vec4	(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler,	glw::GLenum pname,		const tcu::IVec4& expected,	QueryType type);
449void verifyStateSamplerParamIntegerVec4			(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler,	glw::GLenum pname,		const tcu::IVec4& expected,	QueryType type);
450void verifyStateSamplerParamUnsignedIntegerVec4	(tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler,	glw::GLenum pname,		const tcu::UVec4& expected,	QueryType type);
451
452} // StateQueryUtil
453} // gls
454} // deqp
455
456#endif // _GLSSTATEQUERYUTIL_HPP
457