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
33 namespace glu
34 {
35 class CallLogWrapper;
36 } // glu
37
38 namespace deqp
39 {
40 namespace gls
41 {
42 namespace 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 *//*--------------------------------------------------------------------*/
61 template <typename T>
roundGLfloatToNearestIntegerHalfUp(float val)62 T 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 *//*--------------------------------------------------------------------*/
74 template <typename T>
roundGLfloatToNearestIntegerHalfDown(float val)75 T roundGLfloatToNearestIntegerHalfDown (float val)
76 {
77 return (T)(deFloatCeil(val - 0.5f));
78 }
79
80 template <typename T>
81 class StateQueryMemoryWriteGuard
82 {
83 public:
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
get(void) const96 const T& get (void) const { return m_value; }
97
98 private:
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
109 template <typename T>
StateQueryMemoryWriteGuard(void)110 StateQueryMemoryWriteGuard<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
122 template <typename T>
operator T&(void)123 StateQueryMemoryWriteGuard<T>::operator T& (void)
124 {
125 return m_value;
126 }
127
128 template <typename T>
operator &(void)129 T* StateQueryMemoryWriteGuard<T>::operator & (void)
130 {
131 return &m_value;
132 }
133
134 template <typename T>
isUndefined() const135 bool 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
143 template <typename T>
isMemoryContaminated() const144 bool StateQueryMemoryWriteGuard<T>::isMemoryContaminated () const
145 {
146 return isPreguardContaminated() || isPostguardContaminated();
147 }
148
149 template <typename T>
isPreguardContaminated(void) const150 bool 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
158 template <typename T>
isPostguardContaminated(void) const159 bool 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
167 template <typename T>
verifyValidity(tcu::TestContext & testCtx) const168 bool 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
203 template <typename T>
verifyValidity(tcu::ResultCollector & result) const204 bool 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
227 template<typename T>
operator <<(std::ostream & str,const StateQueryMemoryWriteGuard<T> & guard)228 std::ostream& operator<< (std::ostream& str, const StateQueryMemoryWriteGuard<T>& guard)
229 {
230 return str << guard.get();
231 }
232
233 // Verifiers
234
235 enum 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
305 enum DataType
306 {
307 DATATYPE_BOOLEAN = 0,
308 DATATYPE_INTEGER,
309 DATATYPE_INTEGER64,
310 DATATYPE_FLOAT16,
311 DATATYPE_FLOAT,
312 DATATYPE_UNSIGNED_INTEGER,
313 DATATYPE_INTEGER_VEC3,
314 DATATYPE_FLOAT_VEC4,
315 DATATYPE_INTEGER_VEC4,
316 DATATYPE_INTEGER64_VEC4,
317 DATATYPE_UNSIGNED_INTEGER_VEC4,
318 DATATYPE_BOOLEAN_VEC4,
319 DATATYPE_POINTER,
320
321 DATATYPE_LAST
322 };
323
324 class QueriedState
325 {
326 public:
327 typedef glw::GLint GLIntVec3[3];
328 typedef glw::GLint GLIntVec4[4];
329 typedef glw::GLuint GLUintVec4[4];
330 typedef glw::GLfloat GLFloatVec4[4];
331 typedef bool BooleanVec4[4];
332 typedef glw::GLint64 GLInt64Vec4[4];
333
334 QueriedState (void);
335 explicit QueriedState (glw::GLint);
336 explicit QueriedState (glw::GLint64);
337 explicit QueriedState (bool);
338 explicit QueriedState (glw::GLfloat);
339 explicit QueriedState (glw::GLuint);
340 explicit QueriedState (const GLIntVec3&);
341 explicit QueriedState (void*);
342 explicit QueriedState (const GLIntVec4&);
343 explicit QueriedState (const GLUintVec4&);
344 explicit QueriedState (const GLFloatVec4&);
345 explicit QueriedState (const BooleanVec4&);
346 explicit QueriedState (const GLInt64Vec4&);
347
348 bool isUndefined (void) const;
349 DataType getType (void) const;
350
351 glw::GLint& getIntAccess (void);
352 glw::GLint64& getInt64Access (void);
353 bool& getBoolAccess (void);
354 glw::GLfloat& getFloatAccess (void);
355 glw::GLuint& getUintAccess (void);
356 GLIntVec3& getIntVec3Access (void);
357 void*& getPtrAccess (void);
358 GLIntVec4& getIntVec4Access (void);
359 GLUintVec4& getUintVec4Access (void);
360 GLFloatVec4& getFloatVec4Access (void);
361 BooleanVec4& getBooleanVec4Access (void);
362 GLInt64Vec4& getInt64Vec4Access (void);
363
364 private:
365 DataType m_type;
366 union
367 {
368 glw::GLint vInt;
369 glw::GLint64 vInt64;
370 bool vBool;
371 glw::GLfloat vFloat;
372 glw::GLuint vUint;
373 GLIntVec3 vIntVec3;
374 void* vPtr;
375 GLIntVec4 vIntVec4;
376 GLUintVec4 vUintVec4;
377 GLFloatVec4 vFloatVec4;
378 BooleanVec4 vBooleanVec4;
379 GLInt64Vec4 vInt64Vec4;
380 } m_v;
381 };
382
383 // query functions
384
385 void queryState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum pname, QueriedState& state);
386 void queryIndexedState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int index, QueriedState& state);
387 void queryAttributeState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int index, QueriedState& state);
388 void queryFramebufferState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state);
389 void queryProgramState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint program, glw::GLenum pname, QueriedState& state);
390 void queryPipelineState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint pipeline, glw::GLenum pname, QueriedState& state);
391 void queryTextureParamState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state);
392 void queryTextureLevelState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int level, glw::GLenum pname, QueriedState& state);
393 void queryPointerState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum pname, QueriedState& state);
394 void queryObjectState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint handle, QueriedState& state);
395 void queryQueryState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state);
396 void querySamplerState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint sampler, glw::GLenum pname, QueriedState& state);
397
398 // verification functions
399
400 void verifyBoolean (tcu::ResultCollector& result, QueriedState& state, bool expected);
401 void verifyInteger (tcu::ResultCollector& result, QueriedState& state, int expected);
402 void verifyIntegerMin (tcu::ResultCollector& result, QueriedState& state, int minValue);
403 void verifyIntegerMax (tcu::ResultCollector& result, QueriedState& state, int maxValue);
404 void verifyIntegersEqual (tcu::ResultCollector& result, QueriedState& stateA, QueriedState& stateB);
405 void verifyFloat (tcu::ResultCollector& result, QueriedState& state, float expected);
406 void verifyFloatMin (tcu::ResultCollector& result, QueriedState& state, float minValue);
407 void verifyFloatMax (tcu::ResultCollector& result, QueriedState& state, float maxValue);
408 void verifyIntegerVec3 (tcu::ResultCollector& result, QueriedState& state, const tcu::IVec3& expected);
409 void verifyIntegerVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::IVec4& expected);
410 void verifyUnsignedIntegerVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::UVec4& expected);
411 void verifyFloatVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::Vec4& expected);
412 void verifyBooleanVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::BVec4& expected);
413 void verifyPointer (tcu::ResultCollector& result, QueriedState& state, const void* expected);
414 void verifyNormalizedI32Vec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::IVec4& expected);
415
416 // Helper functions that both query and verify
417
418 void verifyStateBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, bool expected, QueryType type);
419 void verifyStateInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int expected, QueryType type);
420 void verifyStateIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int minValue, QueryType type);
421 void verifyStateIntegerMax (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int maxValue, QueryType type);
422 void verifyStateIntegerEqualToOther (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum other, QueryType type);
423 void verifyStateFloat (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float reference, QueryType type);
424 void verifyStateFloatMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float minValue, QueryType type);
425 void verifyStateFloatMax (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float maxValue, QueryType type);
426 void verifyStatePointer (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, const void* expected, QueryType type);
427 void verifyStateIndexedBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, bool expected, QueryType type);
428 void verifyStateIndexedBooleanVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, const tcu::BVec4& expected, QueryType type);
429 void verifyStateIndexedInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int expected, QueryType type);
430 void verifyStateIndexedIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int minValue, QueryType type);
431 void verifyStateAttributeInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int expected, QueryType type);
432 void verifyStateFramebufferInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type);
433 void verifyStateFramebufferIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int minValue, QueryType type);
434 void verifyStateProgramInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint program, glw::GLenum pname, int expected, QueryType type);
435 void verifyStateProgramIntegerVec3 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint program, glw::GLenum pname, const tcu::IVec3& expected, QueryType type);
436 void verifyStatePipelineInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint pipeline, glw::GLenum pname, int expected, QueryType type);
437 void verifyStateTextureParamInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type);
438 void verifyStateTextureParamFloat (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, float expected, QueryType type);
439 void verifyStateTextureParamFloatVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::Vec4& expected, QueryType type);
440 void verifyStateTextureParamNormalizedI32Vec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::IVec4& expected, QueryType type);
441 void verifyStateTextureParamIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::IVec4& expected, QueryType type);
442 void verifyStateTextureParamUnsignedIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::UVec4& expected, QueryType type);
443 void verifyStateTextureLevelInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int expected, QueryType type);
444 void verifyStateObjectBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint handle, bool expected, QueryType type);
445 void verifyStateQueryInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type);
446 void verifyStateSamplerParamInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, int expected, QueryType type);
447 void verifyStateSamplerParamFloat (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, float expected, QueryType type);
448 void verifyStateSamplerParamFloatVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::Vec4& expected, QueryType type);
449 void verifyStateSamplerParamNormalizedI32Vec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::IVec4& expected, QueryType type);
450 void verifyStateSamplerParamIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::IVec4& expected, QueryType type);
451 void verifyStateSamplerParamUnsignedIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::UVec4& expected, QueryType type);
452
453 } // StateQueryUtil
454 } // gls
455 } // deqp
456
457 #endif // _GLSSTATEQUERYUTIL_HPP
458