1/*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL (ES) Module
3 * -----------------------------------------------
4 *
5 * Copyright 2015 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 State Query test utils.
22 *//*--------------------------------------------------------------------*/
23#include "glsStateQueryUtil.hpp"
24#include "tcuTestContext.hpp"
25#include "tcuFormatUtil.hpp"
26#include "gluCallLogWrapper.hpp"
27#include "gluStrUtil.hpp"
28#include "glwEnums.hpp"
29#include "deStringUtil.hpp"
30
31namespace deqp
32{
33namespace gls
34{
35namespace StateQueryUtil
36{
37
38static glw::GLboolean mapBoolToGLBoolean (bool b)
39{
40	return (b ? GL_TRUE : GL_FALSE);
41}
42
43static bool checkError (tcu::ResultCollector& result, glu::CallLogWrapper& gl, const char* msg)
44{
45	const glw::GLenum errorCode = gl.glGetError();
46
47	if (errorCode == GL_NO_ERROR)
48		return true;
49
50	result.fail(std::string(msg) + ": glGetError() returned " + glu::getErrorStr(errorCode).toString());
51	return false;
52}
53
54QueriedState::QueriedState (void)
55	: m_type(DATATYPE_LAST)
56{
57}
58
59QueriedState::QueriedState (glw::GLint v)
60	: m_type(DATATYPE_INTEGER)
61{
62	m_v.vInt = v;
63}
64
65QueriedState::QueriedState (glw::GLint64 v)
66	: m_type(DATATYPE_INTEGER64)
67{
68	m_v.vInt64 = v;
69}
70
71QueriedState::QueriedState (bool v)
72	: m_type(DATATYPE_BOOLEAN)
73{
74	m_v.vBool = v;
75}
76
77QueriedState::QueriedState (glw::GLfloat v)
78	: m_type(DATATYPE_FLOAT)
79{
80	m_v.vFloat = v;
81}
82
83QueriedState::QueriedState (glw::GLuint v)
84	: m_type(DATATYPE_UNSIGNED_INTEGER)
85{
86	m_v.vUint = v;
87}
88
89QueriedState::QueriedState (const GLIntVec3& v)
90	: m_type(DATATYPE_INTEGER_VEC3)
91{
92	m_v.vIntVec3[0] = v[0];
93	m_v.vIntVec3[1] = v[1];
94	m_v.vIntVec3[2] = v[2];
95}
96
97QueriedState::QueriedState (void* v)
98	: m_type(DATATYPE_POINTER)
99{
100	m_v.vPtr = v;
101}
102
103QueriedState::QueriedState (const GLIntVec4& v)
104	: m_type(DATATYPE_INTEGER_VEC4)
105{
106	m_v.vIntVec4[0] = v[0];
107	m_v.vIntVec4[1] = v[1];
108	m_v.vIntVec4[2] = v[2];
109	m_v.vIntVec4[3] = v[3];
110}
111
112QueriedState::QueriedState (const GLUintVec4& v)
113	: m_type(DATATYPE_UNSIGNED_INTEGER_VEC4)
114{
115	m_v.vUintVec4[0] = v[0];
116	m_v.vUintVec4[1] = v[1];
117	m_v.vUintVec4[2] = v[2];
118	m_v.vUintVec4[3] = v[3];
119}
120
121QueriedState::QueriedState (const GLFloatVec4& v)
122	: m_type(DATATYPE_FLOAT_VEC4)
123{
124	m_v.vFloatVec4[0] = v[0];
125	m_v.vFloatVec4[1] = v[1];
126	m_v.vFloatVec4[2] = v[2];
127	m_v.vFloatVec4[3] = v[3];
128}
129
130QueriedState::QueriedState (const BooleanVec4& v)
131	: m_type(DATATYPE_BOOLEAN_VEC4)
132{
133	m_v.vBooleanVec4[0] = v[0];
134	m_v.vBooleanVec4[1] = v[1];
135	m_v.vBooleanVec4[2] = v[2];
136	m_v.vBooleanVec4[3] = v[3];
137}
138
139QueriedState::QueriedState (const GLInt64Vec4& v)
140	: m_type(DATATYPE_INTEGER64_VEC4)
141{
142	m_v.vInt64Vec4[0] = v[0];
143	m_v.vInt64Vec4[1] = v[1];
144	m_v.vInt64Vec4[2] = v[2];
145	m_v.vInt64Vec4[3] = v[3];
146}
147
148bool QueriedState::isUndefined (void) const
149{
150	return m_type == DATATYPE_LAST;
151}
152
153DataType QueriedState::getType (void) const
154{
155	return m_type;
156}
157
158glw::GLint& QueriedState::getIntAccess (void)
159{
160	DE_ASSERT(m_type == DATATYPE_INTEGER);
161	return m_v.vInt;
162}
163
164glw::GLint64& QueriedState::getInt64Access (void)
165{
166	DE_ASSERT(m_type == DATATYPE_INTEGER64);
167	return m_v.vInt64;
168}
169
170bool& QueriedState::getBoolAccess (void)
171{
172	DE_ASSERT(m_type == DATATYPE_BOOLEAN);
173	return m_v.vBool;
174}
175
176glw::GLfloat& QueriedState::getFloatAccess (void)
177{
178	DE_ASSERT(m_type == DATATYPE_FLOAT);
179	return m_v.vFloat;
180}
181
182glw::GLuint& QueriedState::getUintAccess (void)
183{
184	DE_ASSERT(m_type == DATATYPE_UNSIGNED_INTEGER);
185	return m_v.vUint;
186}
187
188QueriedState::GLIntVec3& QueriedState::getIntVec3Access (void)
189{
190	DE_ASSERT(m_type == DATATYPE_INTEGER_VEC3);
191	return m_v.vIntVec3;
192}
193
194void*& QueriedState::getPtrAccess (void)
195{
196	DE_ASSERT(m_type == DATATYPE_POINTER);
197	return m_v.vPtr;
198}
199
200QueriedState::GLIntVec4& QueriedState::getIntVec4Access (void)
201{
202	DE_ASSERT(m_type == DATATYPE_INTEGER_VEC4);
203	return m_v.vIntVec4;
204}
205
206QueriedState::GLUintVec4& QueriedState::getUintVec4Access (void)
207{
208	DE_ASSERT(m_type == DATATYPE_UNSIGNED_INTEGER_VEC4);
209	return m_v.vUintVec4;
210}
211
212QueriedState::GLFloatVec4& QueriedState::getFloatVec4Access (void)
213{
214	DE_ASSERT(m_type == DATATYPE_FLOAT_VEC4);
215	return m_v.vFloatVec4;
216}
217
218QueriedState::BooleanVec4& QueriedState::getBooleanVec4Access (void)
219{
220	DE_ASSERT(m_type == DATATYPE_BOOLEAN_VEC4);
221	return m_v.vBooleanVec4;
222}
223
224QueriedState::GLInt64Vec4& QueriedState::getInt64Vec4Access (void)
225{
226	DE_ASSERT(m_type == DATATYPE_INTEGER64_VEC4);
227	return m_v.vInt64Vec4;
228}
229
230// query
231
232static bool verifyBooleanValidity (tcu::ResultCollector& result, glw::GLboolean v)
233{
234	if (v == GL_TRUE || v == GL_FALSE)
235		return true;
236	else
237	{
238		std::ostringstream buf;
239		buf << "Boolean value was not neither GL_TRUE nor GL_FALSE, got " << de::toString(tcu::Format::Hex<2>(v));
240		result.fail(buf.str());
241		return false;
242	}
243}
244
245static bool verifyBooleanVec4Validity (tcu::ResultCollector& result, const glw::GLboolean v[4])
246{
247	bool valid = true;
248
249	for (int i = 0; i < 4; i++)
250	{
251		if (v[i] != GL_TRUE && v[i] != GL_FALSE)
252			valid = false;
253	}
254
255	if (!valid)
256	{
257		std::ostringstream buf;
258		buf << "Boolean vec4 value was not neither GL_TRUE nor GL_FALSE, got (";
259
260		for (int i = 0; i < 4; i++)
261			buf << (i > 0 ? ", " : "") << de::toString(tcu::Format::Hex<2>(v[i]));
262
263		buf << ")";
264
265		result.fail(buf.str());
266	}
267
268	return valid;
269}
270
271void queryState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, QueriedState& state)
272{
273	switch (type)
274	{
275		case QUERY_ISENABLED:
276		{
277			const glw::GLboolean value = gl.glIsEnabled(target);
278
279			if (!checkError(result, gl, "glIsEnabled"))
280				return;
281
282			if (!verifyBooleanValidity(result, value))
283				return;
284
285			state = QueriedState(value == GL_TRUE);
286			break;
287		}
288
289		case QUERY_BOOLEAN:
290		{
291			StateQueryMemoryWriteGuard<glw::GLboolean> value;
292			gl.glGetBooleanv(target, &value);
293
294			if (!checkError(result, gl, "glGetBooleanv"))
295				return;
296
297			if (!value.verifyValidity(result))
298				return;
299			if (!verifyBooleanValidity(result, value))
300				return;
301
302			state = QueriedState(value == GL_TRUE);
303			break;
304		}
305
306		case QUERY_INTEGER:
307		{
308			StateQueryMemoryWriteGuard<glw::GLint> value;
309			gl.glGetIntegerv(target, &value);
310
311			if (!checkError(result, gl, "glGetIntegerv"))
312				return;
313
314			if (!value.verifyValidity(result))
315				return;
316
317			state = QueriedState(value);
318			break;
319		}
320
321		case QUERY_INTEGER64:
322		{
323			StateQueryMemoryWriteGuard<glw::GLint64> value;
324			gl.glGetInteger64v(target, &value);
325
326			if (!checkError(result, gl, "glGetInteger64v"))
327				return;
328
329			if (!value.verifyValidity(result))
330				return;
331
332			state = QueriedState(value);
333			break;
334		}
335
336		case QUERY_FLOAT:
337		{
338			StateQueryMemoryWriteGuard<glw::GLfloat> value;
339			gl.glGetFloatv(target, &value);
340
341			if (!checkError(result, gl, "glGetFloatv"))
342				return;
343
344			if (!value.verifyValidity(result))
345				return;
346
347			state = QueriedState(value);
348			break;
349		}
350
351		default:
352			DE_ASSERT(DE_FALSE);
353			break;
354	}
355}
356
357void queryIndexedState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int index, QueriedState& state)
358{
359	switch (type)
360	{
361		case QUERY_INDEXED_BOOLEAN_VEC4:
362		{
363			StateQueryMemoryWriteGuard<glw::GLboolean[4]> value;
364			gl.glGetBooleani_v(target, index, value);
365
366			if (!checkError(result, gl, "glGetBooleani_v"))
367				return;
368
369			if (!value.verifyValidity(result))
370				return;
371
372			if (!verifyBooleanVec4Validity(result, value))
373				return;
374
375			{
376				bool res[4];
377
378				for (int i = 0; i < 4; i++)
379					res[i] = value[i] == GL_TRUE;
380
381				state = QueriedState(res);
382			}
383
384			break;
385		}
386
387		case QUERY_INDEXED_INTEGER_VEC4:
388		{
389			StateQueryMemoryWriteGuard<glw::GLint[4]> value;
390			gl.glGetIntegeri_v(target, index, value);
391
392			if (!checkError(result, gl, "glGetIntegeri_v"))
393				return;
394
395			if (!value.verifyValidity(result))
396				return;
397
398			state = QueriedState(value);
399			break;
400		}
401
402		case QUERY_INDEXED_INTEGER64_VEC4:
403		{
404			StateQueryMemoryWriteGuard<glw::GLint64[4]> value;
405			gl.glGetInteger64i_v(target, index, value);
406
407			if (!checkError(result, gl, "glGetInteger64i_v"))
408				return;
409
410			if (!value.verifyValidity(result))
411				return;
412
413			state = QueriedState(value);
414			break;
415		}
416
417		case QUERY_INDEXED_ISENABLED:
418		{
419			const glw::GLboolean value = gl.glIsEnabledi(target, index);
420
421			if (!checkError(result, gl, "glIsEnabledi"))
422				return;
423
424			if (!verifyBooleanValidity(result, value))
425				return;
426
427			state = QueriedState(value == GL_TRUE);
428			break;
429		}
430
431		case QUERY_INDEXED_BOOLEAN:
432		{
433			StateQueryMemoryWriteGuard<glw::GLboolean> value;
434			gl.glGetBooleani_v(target, index, &value);
435
436			if (!checkError(result, gl, "glGetBooleani_v"))
437				return;
438
439			if (!value.verifyValidity(result))
440				return;
441			if (!verifyBooleanValidity(result, value))
442				return;
443
444			state = QueriedState(value == GL_TRUE);
445			break;
446		}
447
448		case QUERY_INDEXED_INTEGER:
449		{
450			StateQueryMemoryWriteGuard<glw::GLint> value;
451			gl.glGetIntegeri_v(target, index, &value);
452
453			if (!checkError(result, gl, "glGetIntegeri_v"))
454				return;
455
456			if (!value.verifyValidity(result))
457				return;
458
459			state = QueriedState(value);
460			break;
461		}
462
463		case QUERY_INDEXED_INTEGER64:
464		{
465			StateQueryMemoryWriteGuard<glw::GLint64> value;
466			gl.glGetInteger64i_v(target, index, &value);
467
468			if (!checkError(result, gl, "glGetInteger64i_v"))
469				return;
470
471			if (!value.verifyValidity(result))
472				return;
473
474			state = QueriedState(value);
475			break;
476		}
477
478		default:
479			DE_ASSERT(DE_FALSE);
480			break;
481	}
482}
483
484void queryAttributeState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int index, QueriedState& state)
485{
486	switch (type)
487	{
488		case QUERY_ATTRIBUTE_INTEGER:
489		{
490			StateQueryMemoryWriteGuard<glw::GLint> value;
491			gl.glGetVertexAttribiv(index, target, &value);
492
493			if (!checkError(result, gl, "glGetVertexAttribiv"))
494				return;
495
496			if (!value.verifyValidity(result))
497				return;
498
499			state = QueriedState(value);
500			break;
501		}
502		case QUERY_ATTRIBUTE_FLOAT:
503		{
504			StateQueryMemoryWriteGuard<glw::GLfloat> value;
505			gl.glGetVertexAttribfv(index, target, &value);
506
507			if (!checkError(result, gl, "glGetVertexAttribfv"))
508				return;
509
510			if (!value.verifyValidity(result))
511				return;
512
513			state = QueriedState(value);
514			break;
515		}
516		case QUERY_ATTRIBUTE_PURE_INTEGER:
517		{
518			StateQueryMemoryWriteGuard<glw::GLint> value;
519			gl.glGetVertexAttribIiv(index, target, &value);
520
521			if (!checkError(result, gl, "glGetVertexAttribIiv"))
522				return;
523
524			if (!value.verifyValidity(result))
525				return;
526
527			state = QueriedState(value);
528			break;
529		}
530		case QUERY_ATTRIBUTE_PURE_UNSIGNED_INTEGER:
531		{
532			StateQueryMemoryWriteGuard<glw::GLuint> value;
533			gl.glGetVertexAttribIuiv(index, target, &value);
534
535			if (!checkError(result, gl, "glGetVertexAttribIuiv"))
536				return;
537
538			if (!value.verifyValidity(result))
539				return;
540
541			state = QueriedState(value);
542			break;
543		}
544		default:
545			DE_ASSERT(false);
546	}
547}
548
549void queryFramebufferState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state)
550{
551	switch (type)
552	{
553		case QUERY_FRAMEBUFFER_INTEGER:
554		{
555			StateQueryMemoryWriteGuard<glw::GLint> value;
556			gl.glGetFramebufferParameteriv(target, pname, &value);
557
558			if (!checkError(result, gl, "glGetVertexAttribiv"))
559				return;
560
561			if (!value.verifyValidity(result))
562				return;
563
564			state = QueriedState(value);
565			break;
566		}
567		default:
568			DE_ASSERT(false);
569	}
570}
571
572void queryProgramState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint program, glw::GLenum pname, QueriedState& state)
573{
574	switch (type)
575	{
576		case QUERY_PROGRAM_INTEGER:
577		{
578			StateQueryMemoryWriteGuard<glw::GLint> value;
579			gl.glGetProgramiv(program, pname, &value);
580
581			if (!checkError(result, gl, "glGetProgramiv"))
582				return;
583
584			if (!value.verifyValidity(result))
585				return;
586
587			state = QueriedState(value);
588			break;
589		}
590		case QUERY_PROGRAM_INTEGER_VEC3:
591		{
592			StateQueryMemoryWriteGuard<glw::GLint[3]> value;
593			gl.glGetProgramiv(program, pname, value);
594
595			if (!checkError(result, gl, "glGetProgramiv"))
596				return;
597
598			if (!value.verifyValidity(result))
599				return;
600
601			state = QueriedState(value);
602			break;
603		}
604		default:
605			DE_ASSERT(false);
606	}
607}
608
609void queryPipelineState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint pipeline, glw::GLenum pname, QueriedState& state)
610{
611	switch (type)
612	{
613		case QUERY_PIPELINE_INTEGER:
614		{
615			StateQueryMemoryWriteGuard<glw::GLint> value;
616			gl.glGetProgramPipelineiv(pipeline, pname, &value);
617
618			if (!checkError(result, gl, "glGetProgramiv"))
619				return;
620
621			if (!value.verifyValidity(result))
622				return;
623
624			state = QueriedState(value);
625			break;
626		}
627		default:
628			DE_ASSERT(false);
629	}
630}
631
632void queryTextureParamState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state)
633{
634	switch (type)
635	{
636		case QUERY_TEXTURE_PARAM_INTEGER:
637		{
638			StateQueryMemoryWriteGuard<glw::GLint> value;
639			gl.glGetTexParameteriv(target, pname, &value);
640
641			if (!checkError(result, gl, "glGetTexParameteriv"))
642				return;
643
644			if (!value.verifyValidity(result))
645				return;
646
647			state = QueriedState(value);
648			break;
649		}
650		case QUERY_TEXTURE_PARAM_FLOAT:
651		{
652			StateQueryMemoryWriteGuard<glw::GLfloat> value;
653			gl.glGetTexParameterfv(target, pname, &value);
654
655			if (!checkError(result, gl, "glGetTexParameterfv"))
656				return;
657
658			if (!value.verifyValidity(result))
659				return;
660
661			state = QueriedState(value);
662			break;
663		}
664		case QUERY_TEXTURE_PARAM_PURE_INTEGER:
665		{
666			StateQueryMemoryWriteGuard<glw::GLint> value;
667			gl.glGetTexParameterIiv(target, pname, &value);
668
669			if (!checkError(result, gl, "GetTexParameterIiv"))
670				return;
671
672			if (!value.verifyValidity(result))
673				return;
674
675			state = QueriedState(value);
676			break;
677		}
678		case QUERY_TEXTURE_PARAM_PURE_UNSIGNED_INTEGER:
679		{
680			StateQueryMemoryWriteGuard<glw::GLuint> value;
681			gl.glGetTexParameterIuiv(target, pname, &value);
682
683			if (!checkError(result, gl, "GetTexParameterIuiv"))
684				return;
685
686			if (!value.verifyValidity(result))
687				return;
688
689			state = QueriedState(value);
690			break;
691		}
692		case QUERY_TEXTURE_PARAM_INTEGER_VEC4:
693		{
694			StateQueryMemoryWriteGuard<glw::GLint[4]> value;
695			gl.glGetTexParameteriv(target, pname, value);
696
697			if (!checkError(result, gl, "glGetTexParameteriv"))
698				return;
699
700			if (!value.verifyValidity(result))
701				return;
702
703			state = QueriedState(value);
704			break;
705		}
706		case QUERY_TEXTURE_PARAM_FLOAT_VEC4:
707		{
708			StateQueryMemoryWriteGuard<glw::GLfloat[4]> value;
709			gl.glGetTexParameterfv(target, pname, value);
710
711			if (!checkError(result, gl, "glGetTexParameterfv"))
712				return;
713
714			if (!value.verifyValidity(result))
715				return;
716
717			state = QueriedState(value);
718			break;
719		}
720		case QUERY_TEXTURE_PARAM_PURE_INTEGER_VEC4:
721		{
722			StateQueryMemoryWriteGuard<glw::GLint[4]> value;
723			gl.glGetTexParameterIiv(target, pname, value);
724
725			if (!checkError(result, gl, "GetTexParameterIiv"))
726				return;
727
728			if (!value.verifyValidity(result))
729				return;
730
731			state = QueriedState(value);
732			break;
733		}
734		case QUERY_TEXTURE_PARAM_PURE_UNSIGNED_INTEGER_VEC4:
735		{
736			StateQueryMemoryWriteGuard<glw::GLuint[4]> value;
737			gl.glGetTexParameterIuiv(target, pname, value);
738
739			if (!checkError(result, gl, "GetTexParameterIuiv"))
740				return;
741
742			if (!value.verifyValidity(result))
743				return;
744
745			state = QueriedState(value);
746			break;
747		}
748		default:
749			DE_ASSERT(false);
750	}
751}
752
753void queryTextureLevelState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, int level, glw::GLenum pname, QueriedState& state)
754{
755	switch (type)
756	{
757		case QUERY_TEXTURE_LEVEL_INTEGER:
758		{
759			StateQueryMemoryWriteGuard<glw::GLint> value;
760			gl.glGetTexLevelParameteriv(target, level, pname, &value);
761
762			if (!checkError(result, gl, "glGetTexLevelParameteriv"))
763				return;
764
765			if (!value.verifyValidity(result))
766				return;
767
768			state = QueriedState(value);
769			break;
770		}
771		case QUERY_TEXTURE_LEVEL_FLOAT:
772		{
773			StateQueryMemoryWriteGuard<glw::GLfloat> value;
774			gl.glGetTexLevelParameterfv(target, level, pname, &value);
775
776			if (!checkError(result, gl, "glGetTexLevelParameterfv"))
777				return;
778
779			if (!value.verifyValidity(result))
780				return;
781
782			state = QueriedState(value);
783			break;
784		}
785		default:
786			DE_ASSERT(false);
787	}
788}
789
790void queryPointerState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum pname, QueriedState& state)
791{
792	switch (type)
793	{
794		case QUERY_POINTER:
795		{
796			StateQueryMemoryWriteGuard<void*> value;
797			gl.glGetPointerv(pname, &value);
798
799			if (!checkError(result, gl, "glGetPointerv"))
800				return;
801
802			if (!value.verifyValidity(result))
803				return;
804
805			state = QueriedState(value);
806			break;
807		}
808		default:
809			DE_ASSERT(false);
810	}
811}
812
813void queryObjectState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint handle, QueriedState& state)
814{
815	switch (type)
816	{
817		case QUERY_ISTEXTURE:
818		{
819			const glw::GLboolean value = gl.glIsTexture(handle);
820
821			if (!checkError(result, gl, "glIsTexture"))
822				return;
823
824			if (!verifyBooleanValidity(result, value))
825				return;
826
827			state = QueriedState(value == GL_TRUE);
828			break;
829		}
830		default:
831			DE_ASSERT(false);
832	}
833}
834
835void queryQueryState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLenum target, glw::GLenum pname, QueriedState& state)
836{
837	switch (type)
838	{
839		case QUERY_QUERY:
840		{
841			StateQueryMemoryWriteGuard<glw::GLint> value;
842			gl.glGetQueryiv(target, pname, &value);
843
844			if (!checkError(result, gl, "glGetQueryiv"))
845				return;
846
847			if (!value.verifyValidity(result))
848				return;
849
850			state = QueriedState(value);
851			break;
852		}
853		default:
854			DE_ASSERT(false);
855	}
856}
857
858void querySamplerState (tcu::ResultCollector& result, glu::CallLogWrapper& gl, QueryType type, glw::GLuint sampler, glw::GLenum pname, QueriedState& state)
859{
860	switch (type)
861	{
862		case QUERY_SAMPLER_PARAM_INTEGER:
863		{
864			StateQueryMemoryWriteGuard<glw::GLint> value;
865			gl.glGetSamplerParameteriv(sampler, pname, &value);
866
867			if (!checkError(result, gl, "glGetSamplerParameteriv"))
868				return;
869
870			if (!value.verifyValidity(result))
871				return;
872
873			state = QueriedState(value);
874			break;
875		}
876		case QUERY_SAMPLER_PARAM_FLOAT:
877		{
878			StateQueryMemoryWriteGuard<glw::GLfloat> value;
879			gl.glGetSamplerParameterfv(sampler, pname, &value);
880
881			if (!checkError(result, gl, "glGetSamplerParameteriv"))
882				return;
883
884			if (!value.verifyValidity(result))
885				return;
886
887			state = QueriedState(value);
888			break;
889		}
890		case QUERY_SAMPLER_PARAM_PURE_INTEGER:
891		{
892			StateQueryMemoryWriteGuard<glw::GLint> value;
893			gl.glGetSamplerParameterIiv(sampler, pname, &value);
894
895			if (!checkError(result, gl, "glGetSamplerParameterIiv"))
896				return;
897
898			if (!value.verifyValidity(result))
899				return;
900
901			state = QueriedState(value);
902			break;
903		}
904		case QUERY_SAMPLER_PARAM_PURE_UNSIGNED_INTEGER:
905		{
906			StateQueryMemoryWriteGuard<glw::GLuint> value;
907			gl.glGetSamplerParameterIuiv(sampler, pname, &value);
908
909			if (!checkError(result, gl, "glGetSamplerParameterIuiv"))
910				return;
911
912			if (!value.verifyValidity(result))
913				return;
914
915			state = QueriedState(value);
916			break;
917		}
918		case QUERY_SAMPLER_PARAM_INTEGER_VEC4:
919		{
920			StateQueryMemoryWriteGuard<glw::GLint[4]> value;
921			gl.glGetSamplerParameteriv(sampler, pname, value);
922
923			if (!checkError(result, gl, "glGetSamplerParameteriv"))
924				return;
925
926			if (!value.verifyValidity(result))
927				return;
928
929			state = QueriedState(value);
930			break;
931		}
932		case QUERY_SAMPLER_PARAM_FLOAT_VEC4:
933		{
934			StateQueryMemoryWriteGuard<glw::GLfloat[4]> value;
935			gl.glGetSamplerParameterfv(sampler, pname, value);
936
937			if (!checkError(result, gl, "glGetSamplerParameteriv"))
938				return;
939
940			if (!value.verifyValidity(result))
941				return;
942
943			state = QueriedState(value);
944			break;
945		}
946		case QUERY_SAMPLER_PARAM_PURE_INTEGER_VEC4:
947		{
948			StateQueryMemoryWriteGuard<glw::GLint[4]> value;
949			gl.glGetSamplerParameterIiv(sampler, pname, value);
950
951			if (!checkError(result, gl, "glGetSamplerParameterIiv"))
952				return;
953
954			if (!value.verifyValidity(result))
955				return;
956
957			state = QueriedState(value);
958			break;
959		}
960		case QUERY_SAMPLER_PARAM_PURE_UNSIGNED_INTEGER_VEC4:
961		{
962			StateQueryMemoryWriteGuard<glw::GLuint[4]> value;
963			gl.glGetSamplerParameterIuiv(sampler, pname, value);
964
965			if (!checkError(result, gl, "glGetSamplerParameterIuiv"))
966				return;
967
968			if (!value.verifyValidity(result))
969				return;
970
971			state = QueriedState(value);
972			break;
973		}
974		default:
975			DE_ASSERT(false);
976	}
977}
978
979// verify
980
981void verifyBoolean (tcu::ResultCollector& result, QueriedState& state, bool expected)
982{
983	switch (state.getType())
984	{
985		case DATATYPE_BOOLEAN:
986		{
987			if (state.getBoolAccess() != expected)
988			{
989				std::ostringstream buf;
990				buf << "Expected " << glu::getBooleanStr(mapBoolToGLBoolean(expected)) << ", got " << glu::getBooleanStr(mapBoolToGLBoolean(state.getBoolAccess()));
991				result.fail(buf.str());
992			}
993			break;
994		}
995
996		case DATATYPE_INTEGER:
997		{
998			const glw::GLint reference = expected ? 1 : 0;
999			if (state.getIntAccess() != reference)
1000			{
1001				std::ostringstream buf;
1002				buf << "Expected " << reference << ", got " << state.getIntAccess();
1003				result.fail(buf.str());
1004			}
1005			break;
1006		}
1007
1008		case DATATYPE_INTEGER64:
1009		{
1010			const glw::GLint64 reference = expected ? 1 : 0;
1011			if (state.getInt64Access() != reference)
1012			{
1013				std::ostringstream buf;
1014				buf << "Expected " << reference << ", got " << state.getInt64Access();
1015				result.fail(buf.str());
1016			}
1017			break;
1018		}
1019
1020		case DATATYPE_FLOAT:
1021		{
1022			const glw::GLfloat reference = expected ? 1.0f : 0.0f;
1023			if (state.getFloatAccess() != reference)
1024			{
1025				std::ostringstream buf;
1026				buf << "Expected " << reference << ", got " << state.getFloatAccess();
1027				result.fail(buf.str());
1028			}
1029			break;
1030		}
1031
1032		default:
1033			DE_ASSERT(DE_FALSE);
1034			break;
1035	}
1036}
1037
1038void verifyInteger (tcu::ResultCollector& result, QueriedState& state, int expected)
1039{
1040	switch (state.getType())
1041	{
1042		case DATATYPE_BOOLEAN:
1043		{
1044			const bool reference = (expected != 0);
1045			if (state.getBoolAccess() != reference)
1046			{
1047				std::ostringstream buf;
1048				buf << "Expected " << glu::getBooleanStr(mapBoolToGLBoolean(reference)) << ", got " << glu::getBooleanStr(mapBoolToGLBoolean(state.getBoolAccess()));
1049				result.fail(buf.str());
1050			}
1051			break;
1052		}
1053
1054		case DATATYPE_INTEGER:
1055		{
1056			const glw::GLint reference = expected;
1057			if (state.getIntAccess() != reference)
1058			{
1059				std::ostringstream buf;
1060				buf << "Expected " << reference << "(" << de::toString(tcu::Format::Hex<8>(reference))
1061					<< ") , got " << state.getIntAccess() << "(" << de::toString(tcu::Format::Hex<8>(state.getIntAccess())) << ")";
1062				result.fail(buf.str());
1063			}
1064			break;
1065		}
1066
1067		case DATATYPE_INTEGER64:
1068		{
1069			const glw::GLint64 reference = (glw::GLint64)expected;
1070			if (state.getInt64Access() != reference)
1071			{
1072				std::ostringstream buf;
1073				buf << "Expected " << reference << "(" << de::toString(tcu::Format::Hex<8>(reference)) << "), got "
1074					<< state.getInt64Access() << "(" << de::toString(tcu::Format::Hex<8>(state.getInt64Access())) << ")";
1075				result.fail(buf.str());
1076			}
1077			break;
1078		}
1079
1080		case DATATYPE_FLOAT:
1081		{
1082			const glw::GLfloat refValueMin = deInt32ToFloatRoundToNegInf(expected);
1083			const glw::GLfloat refValueMax = deInt32ToFloatRoundToPosInf(expected);
1084
1085			if (state.getFloatAccess() < refValueMin ||
1086				state.getFloatAccess() > refValueMax ||
1087				deIsNaN(state.getFloatAccess()))
1088			{
1089				std::ostringstream buf;
1090
1091				if (refValueMin == refValueMax)
1092					buf << "Expected " << refValueMin << ", got " << state.getFloatAccess();
1093				else
1094					buf << "Expected in range [" << refValueMin << ", " << refValueMax << "], got " << state.getFloatAccess();
1095
1096				result.fail(buf.str());
1097			}
1098			break;
1099		}
1100
1101		case DATATYPE_UNSIGNED_INTEGER:
1102		{
1103			const glw::GLuint reference = (glw::GLuint)expected;
1104			if (state.getUintAccess() != reference)
1105			{
1106				std::ostringstream buf;
1107				buf << "Expected " << reference << "(" << de::toString(tcu::Format::Hex<8>(reference)) << "), got "
1108					<< state.getInt64Access() << "(" << de::toString(tcu::Format::Hex<8>(state.getInt64Access())) << ")";
1109				result.fail(buf.str());
1110			}
1111			break;
1112		}
1113
1114		default:
1115			DE_ASSERT(DE_FALSE);
1116			break;
1117	}
1118}
1119
1120void verifyIntegerMin (tcu::ResultCollector& result, QueriedState& state, int minValue)
1121{
1122	switch (state.getType())
1123	{
1124		case DATATYPE_BOOLEAN:
1125		{
1126			if (minValue > 0 && state.getBoolAccess() != true)
1127			{
1128				std::ostringstream buf;
1129				buf << "Expected GL_TRUE, got GL_FALSE";
1130				result.fail(buf.str());
1131			}
1132			break;
1133		}
1134
1135		case DATATYPE_INTEGER:
1136		{
1137			if (state.getIntAccess() < minValue)
1138			{
1139				std::ostringstream buf;
1140				buf << "Expected greater or equal to " << minValue << ", got " << state.getIntAccess();
1141				result.fail(buf.str());
1142			}
1143			break;
1144		}
1145
1146		case DATATYPE_INTEGER64:
1147		{
1148			if (state.getInt64Access() < minValue)
1149			{
1150				std::ostringstream buf;
1151				buf << "Expected greater or equal to " << minValue << ", got " << state.getInt64Access();
1152				result.fail(buf.str());
1153			}
1154			break;
1155		}
1156
1157		case DATATYPE_FLOAT:
1158		{
1159			if (state.getFloatAccess() < deInt32ToFloatRoundToNegInf(minValue) || deIsNaN(state.getFloatAccess()))
1160			{
1161				std::ostringstream buf;
1162				buf << "Expected greater or equal to " << minValue << ", got " << state.getFloatAccess();
1163				result.fail(buf.str());
1164			}
1165			break;
1166		}
1167
1168		default:
1169			DE_ASSERT(DE_FALSE);
1170			break;
1171	}
1172}
1173
1174void verifyIntegerMax (tcu::ResultCollector& result, QueriedState& state, int maxValue)
1175{
1176	switch (state.getType())
1177	{
1178		case DATATYPE_BOOLEAN:
1179		{
1180			if (maxValue < 0 && state.getBoolAccess() != true)
1181			{
1182				std::ostringstream buf;
1183				buf << "Expected GL_TRUE, got GL_FALSE";
1184				result.fail(buf.str());
1185			}
1186			break;
1187		}
1188
1189		case DATATYPE_INTEGER:
1190		{
1191			if (state.getIntAccess() > maxValue)
1192			{
1193				std::ostringstream buf;
1194				buf << "Expected less or equal to " << maxValue << ", got " << state.getIntAccess();
1195				result.fail(buf.str());
1196			}
1197			break;
1198		}
1199
1200		case DATATYPE_INTEGER64:
1201		{
1202			if (state.getInt64Access() > maxValue)
1203			{
1204				std::ostringstream buf;
1205				buf << "Expected less or equal to " << maxValue << ", got " << state.getInt64Access();
1206				result.fail(buf.str());
1207			}
1208			break;
1209		}
1210
1211		case DATATYPE_FLOAT:
1212		{
1213			if (state.getFloatAccess() > deInt32ToFloatRoundToPosInf(maxValue) || deIsNaN(state.getFloatAccess()))
1214			{
1215				std::ostringstream buf;
1216				buf << "Expected less or equal to " << maxValue << ", got " << state.getFloatAccess();
1217				result.fail(buf.str());
1218			}
1219			break;
1220		}
1221
1222		default:
1223			DE_ASSERT(DE_FALSE);
1224			break;
1225	}
1226}
1227
1228void verifyFloat (tcu::ResultCollector& result, QueriedState& state, float expected)
1229{
1230	switch (state.getType())
1231	{
1232		case DATATYPE_BOOLEAN:
1233		{
1234			const bool reference = (expected != 0.0f);
1235
1236			if (state.getBoolAccess() != reference)
1237			{
1238				std::ostringstream buf;
1239				buf << "Expected " << glu::getBooleanStr(mapBoolToGLBoolean(reference)) << ", got " << glu::getBooleanStr(mapBoolToGLBoolean(state.getBoolAccess()));
1240				result.fail(buf.str());
1241			}
1242			break;
1243		}
1244
1245		case DATATYPE_INTEGER:
1246		{
1247			const glw::GLint refValueMin = roundGLfloatToNearestIntegerHalfDown<glw::GLint>(expected);
1248			const glw::GLint refValueMax = roundGLfloatToNearestIntegerHalfUp<glw::GLint>(expected);
1249
1250			if (state.getIntAccess() < refValueMin ||
1251				state.getIntAccess() > refValueMax)
1252			{
1253				std::ostringstream buf;
1254
1255				if (refValueMin == refValueMax)
1256					buf << "Expected " << refValueMin << ", got " << state.getIntAccess();
1257				else
1258					buf << "Expected in range [" << refValueMin << ", " << refValueMax << "], got " << state.getIntAccess();
1259
1260				result.fail(buf.str());
1261			}
1262			break;
1263		}
1264
1265		case DATATYPE_FLOAT:
1266		{
1267			if (state.getFloatAccess() != expected)
1268			{
1269				std::ostringstream buf;
1270				buf << "Expected " << expected << ", got " << state.getFloatAccess();
1271				result.fail(buf.str());
1272			}
1273			break;
1274		}
1275
1276		case DATATYPE_INTEGER64:
1277		{
1278			const glw::GLint64 refValueMin = roundGLfloatToNearestIntegerHalfDown<glw::GLint64>(expected);
1279			const glw::GLint64 refValueMax = roundGLfloatToNearestIntegerHalfUp<glw::GLint64>(expected);
1280
1281			if (state.getInt64Access() < refValueMin ||
1282				state.getInt64Access() > refValueMax)
1283			{
1284				std::ostringstream buf;
1285
1286				if (refValueMin == refValueMax)
1287					buf << "Expected " << refValueMin << ", got " << state.getInt64Access();
1288				else
1289					buf << "Expected in range [" << refValueMin << ", " << refValueMax << "], got " << state.getInt64Access();
1290
1291				result.fail(buf.str());
1292			}
1293			break;
1294		}
1295
1296		case DATATYPE_UNSIGNED_INTEGER:
1297		{
1298			const glw::GLuint refValueMin = roundGLfloatToNearestIntegerHalfDown<glw::GLuint>(expected);
1299			const glw::GLuint refValueMax = roundGLfloatToNearestIntegerHalfUp<glw::GLuint>(expected);
1300
1301			if (state.getUintAccess() < refValueMin ||
1302				state.getUintAccess() > refValueMax)
1303			{
1304				std::ostringstream buf;
1305
1306				if (refValueMin == refValueMax)
1307					buf << "Expected " << refValueMin << ", got " << state.getUintAccess();
1308				else
1309					buf << "Expected in range [" << refValueMin << ", " << refValueMax << "], got " << state.getUintAccess();
1310
1311				result.fail(buf.str());
1312			}
1313			break;
1314		}
1315
1316		default:
1317			DE_ASSERT(DE_FALSE);
1318			break;
1319	}
1320}
1321
1322void verifyFloatMin (tcu::ResultCollector& result, QueriedState& state, float minValue)
1323{
1324	switch (state.getType())
1325	{
1326		case DATATYPE_BOOLEAN:
1327		{
1328			if (minValue > 0.0f && state.getBoolAccess() != true)
1329				result.fail("expected GL_TRUE, got GL_FALSE");
1330			break;
1331		}
1332
1333		case DATATYPE_INTEGER:
1334		{
1335			const glw::GLint refValue = roundGLfloatToNearestIntegerHalfDown<glw::GLint>(minValue);
1336
1337			if (state.getIntAccess() < refValue)
1338			{
1339				std::ostringstream buf;
1340				buf << "Expected greater or equal to " << refValue << ", got " << state.getIntAccess();
1341				result.fail(buf.str());
1342			}
1343			break;
1344		}
1345
1346		case DATATYPE_FLOAT:
1347		{
1348			if (state.getFloatAccess() < minValue || deIsNaN(state.getFloatAccess()))
1349			{
1350				std::ostringstream buf;
1351				buf << "Expected greater or equal to " << minValue << ", got " << state.getFloatAccess();
1352				result.fail(buf.str());
1353			}
1354			break;
1355		}
1356
1357		case DATATYPE_INTEGER64:
1358		{
1359			const glw::GLint64 refValue = roundGLfloatToNearestIntegerHalfDown<glw::GLint64>(minValue);
1360
1361			if (state.getInt64Access() < refValue)
1362			{
1363				std::ostringstream buf;
1364				buf << "Expected greater or equal to " << refValue << ", got " << state.getInt64Access();
1365				result.fail(buf.str());
1366			}
1367			break;
1368		}
1369
1370		default:
1371			DE_ASSERT(DE_FALSE);
1372			break;
1373	}
1374}
1375
1376void verifyFloatMax (tcu::ResultCollector& result, QueriedState& state, float maxValue)
1377{
1378	switch (state.getType())
1379	{
1380		case DATATYPE_BOOLEAN:
1381		{
1382			if (maxValue < 0.0f && state.getBoolAccess() != true)
1383				result.fail("expected GL_TRUE, got GL_FALSE");
1384			break;
1385		}
1386
1387		case DATATYPE_INTEGER:
1388		{
1389			const glw::GLint refValue = roundGLfloatToNearestIntegerHalfUp<glw::GLint>(maxValue);
1390
1391			if (state.getIntAccess() > refValue)
1392			{
1393				std::ostringstream buf;
1394				buf << "Expected less or equal to " << refValue << ", got " << state.getIntAccess();
1395				result.fail(buf.str());
1396			}
1397			break;
1398		}
1399
1400		case DATATYPE_FLOAT:
1401		{
1402			if (state.getFloatAccess() > maxValue || deIsNaN(state.getFloatAccess()))
1403			{
1404				std::ostringstream buf;
1405				buf << "Expected less or equal to " << maxValue << ", got " << state.getFloatAccess();
1406				result.fail(buf.str());
1407			}
1408			break;
1409		}
1410
1411		case DATATYPE_INTEGER64:
1412		{
1413			const glw::GLint64 refValue = roundGLfloatToNearestIntegerHalfUp<glw::GLint64>(maxValue);
1414
1415			if (state.getInt64Access() > refValue)
1416			{
1417				std::ostringstream buf;
1418				buf << "Expected less or equal to " << refValue << ", got " << state.getInt64Access();
1419				result.fail(buf.str());
1420			}
1421			break;
1422		}
1423
1424		default:
1425			DE_ASSERT(DE_FALSE);
1426			break;
1427	}
1428}
1429
1430void verifyIntegerVec3 (tcu::ResultCollector& result, QueriedState& state, const tcu::IVec3& expected)
1431{
1432	switch (state.getType())
1433	{
1434		case DATATYPE_INTEGER_VEC3:
1435		{
1436			if (state.getIntVec3Access()[0] != expected[0] ||
1437				state.getIntVec3Access()[1] != expected[1] ||
1438				state.getIntVec3Access()[2] != expected[2])
1439			{
1440				std::ostringstream buf;
1441				buf << "Expected " << expected << ", got " << tcu::formatArray(state.getIntVec3Access());
1442				result.fail(buf.str());
1443			}
1444			break;
1445		}
1446
1447		default:
1448			DE_ASSERT(DE_FALSE);
1449			break;
1450	}
1451}
1452
1453void verifyIntegerVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::IVec4& expected)
1454{
1455	switch (state.getType())
1456	{
1457		case DATATYPE_INTEGER_VEC4:
1458		{
1459			if (state.getIntVec4Access()[0] != expected[0] ||
1460				state.getIntVec4Access()[1] != expected[1] ||
1461				state.getIntVec4Access()[2] != expected[2] ||
1462				state.getIntVec4Access()[3] != expected[3])
1463			{
1464				std::ostringstream buf;
1465				buf << "Expected " << expected << ", got " << tcu::formatArray(state.getIntVec4Access());
1466				result.fail(buf.str());
1467			}
1468			break;
1469		}
1470
1471		default:
1472			DE_ASSERT(DE_FALSE);
1473			break;
1474	}
1475}
1476
1477void verifyUnsignedIntegerVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::UVec4& expected)
1478{
1479	switch (state.getType())
1480	{
1481		case DATATYPE_UNSIGNED_INTEGER_VEC4:
1482		{
1483			if (state.getUintVec4Access()[0] != expected[0] ||
1484				state.getUintVec4Access()[1] != expected[1] ||
1485				state.getUintVec4Access()[2] != expected[2] ||
1486				state.getUintVec4Access()[3] != expected[3])
1487			{
1488				std::ostringstream buf;
1489				buf << "Expected " << expected << ", got " << tcu::formatArray(state.getUintVec4Access());
1490				result.fail(buf.str());
1491			}
1492			break;
1493		}
1494
1495		default:
1496			DE_ASSERT(DE_FALSE);
1497			break;
1498	}
1499}
1500
1501void verifyBooleanVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::BVec4& expected)
1502{
1503	switch (state.getType())
1504	{
1505		case DATATYPE_BOOLEAN_VEC4:
1506		{
1507			const glw::GLboolean referenceVec4[4] =
1508			{
1509				mapBoolToGLBoolean(expected[0]),
1510				mapBoolToGLBoolean(expected[1]),
1511				mapBoolToGLBoolean(expected[2]),
1512				mapBoolToGLBoolean(expected[3])
1513			};
1514
1515			const glw::GLboolean resultVec4[4] =
1516			{
1517				mapBoolToGLBoolean(state.getBooleanVec4Access()[0]),
1518				mapBoolToGLBoolean(state.getBooleanVec4Access()[1]),
1519				mapBoolToGLBoolean(state.getBooleanVec4Access()[2]),
1520				mapBoolToGLBoolean(state.getBooleanVec4Access()[3])
1521			};
1522
1523			if (resultVec4[0] != referenceVec4[0] ||
1524				resultVec4[1] != referenceVec4[1] ||
1525				resultVec4[2] != referenceVec4[2] ||
1526				resultVec4[3] != referenceVec4[3])
1527			{
1528				std::ostringstream buf;
1529				buf << "Expected " << glu::getBooleanPointerStr(referenceVec4, 4) << ", got " << glu::getBooleanPointerStr(resultVec4, 4);
1530				result.fail(buf.str());
1531			}
1532
1533			break;
1534		}
1535		case DATATYPE_FLOAT_VEC4:
1536		{
1537			const glw::GLfloat reference[4] =
1538			{
1539				(expected[0] ? 1.0f : 0.0f),
1540				(expected[1] ? 1.0f : 0.0f),
1541				(expected[2] ? 1.0f : 0.0f),
1542				(expected[3] ? 1.0f : 0.0f)
1543			};
1544
1545			if (state.getFloatVec4Access()[0] != reference[0] ||
1546				state.getFloatVec4Access()[1] != reference[1] ||
1547				state.getFloatVec4Access()[2] != reference[2] ||
1548				state.getFloatVec4Access()[3] != reference[3])
1549			{
1550				std::ostringstream buf;
1551				buf << "Expected " << reference << ", got " << tcu::formatArray(state.getFloatVec4Access());
1552				result.fail(buf.str());
1553			}
1554			break;
1555		}
1556		case DATATYPE_INTEGER_VEC4:
1557		{
1558			const glw::GLint reference[4] =
1559			{
1560				(expected[0] ? 1 : 0),
1561				(expected[1] ? 1 : 0),
1562				(expected[2] ? 1 : 0),
1563				(expected[3] ? 1 : 0)
1564			};
1565
1566			if (state.getIntVec4Access()[0] != reference[0] ||
1567				state.getIntVec4Access()[1] != reference[1] ||
1568				state.getIntVec4Access()[2] != reference[2] ||
1569				state.getIntVec4Access()[3] != reference[3])
1570			{
1571				std::ostringstream buf;
1572				buf << "Expected " << reference << ", got " << tcu::formatArray(state.getIntVec4Access());
1573				result.fail(buf.str());
1574			}
1575			break;
1576		}
1577		case DATATYPE_INTEGER64_VEC4:
1578		{
1579			const glw::GLint64 reference[4] =
1580			{
1581				(expected[0] ? 1 : 0),
1582				(expected[1] ? 1 : 0),
1583				(expected[2] ? 1 : 0),
1584				(expected[3] ? 1 : 0)
1585			};
1586
1587			if (state.getInt64Vec4Access()[0] != reference[0] ||
1588				state.getInt64Vec4Access()[1] != reference[1] ||
1589				state.getInt64Vec4Access()[2] != reference[2] ||
1590				state.getInt64Vec4Access()[3] != reference[3])
1591			{
1592				std::ostringstream buf;
1593				buf << "Expected " << reference << ", got " << tcu::formatArray(state.getInt64Vec4Access());
1594				result.fail(buf.str());
1595			}
1596			break;
1597		}
1598		case DATATYPE_UNSIGNED_INTEGER_VEC4:
1599		{
1600			const glw::GLuint reference[4] =
1601			{
1602				(expected[0] ? 1u : 0u),
1603				(expected[1] ? 1u : 0u),
1604				(expected[2] ? 1u : 0u),
1605				(expected[3] ? 1u : 0u)
1606			};
1607
1608			if (state.getUintVec4Access()[0] != reference[0] ||
1609				state.getUintVec4Access()[1] != reference[1] ||
1610				state.getUintVec4Access()[2] != reference[2] ||
1611				state.getUintVec4Access()[3] != reference[3])
1612			{
1613				std::ostringstream buf;
1614				buf << "Expected " << reference << ", got " << tcu::formatArray(state.getUintVec4Access());
1615				result.fail(buf.str());
1616			}
1617			break;
1618		}
1619
1620		default:
1621			DE_ASSERT(DE_FALSE);
1622			break;
1623	}
1624}
1625
1626void verifyFloatVec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::Vec4& expected)
1627{
1628	switch (state.getType())
1629	{
1630		case DATATYPE_FLOAT_VEC4:
1631		{
1632			if (state.getFloatVec4Access()[0] != expected[0] ||
1633				state.getFloatVec4Access()[1] != expected[1] ||
1634				state.getFloatVec4Access()[2] != expected[2] ||
1635				state.getFloatVec4Access()[3] != expected[3])
1636			{
1637				std::ostringstream buf;
1638				buf << "Expected " << expected << ", got " << tcu::formatArray(state.getFloatVec4Access());
1639				result.fail(buf.str());
1640			}
1641			break;
1642		}
1643		case DATATYPE_INTEGER_VEC4:
1644		{
1645			bool				anyError = false;
1646			std::ostringstream	expectation;
1647
1648			for (int ndx = 0; ndx < 4; ++ndx)
1649			{
1650				const glw::GLint refValueMin = roundGLfloatToNearestIntegerHalfDown<glw::GLint>(expected[ndx]);
1651				const glw::GLint refValueMax = roundGLfloatToNearestIntegerHalfUp<glw::GLint>(expected[ndx]);
1652
1653				if (state.getIntVec4Access()[ndx] < refValueMin ||
1654					state.getIntVec4Access()[ndx] > refValueMax)
1655				{
1656					std::ostringstream buf;
1657
1658					if (ndx > 0)
1659						expectation << " ,";
1660
1661					if (refValueMin == refValueMax)
1662						buf << refValueMin;
1663					else
1664						buf << "[" << refValueMin << ", " << refValueMax << "]";
1665				}
1666			}
1667
1668			if (anyError)
1669			{
1670				std::ostringstream buf;
1671				buf << "Expected {" << expectation.str() << "}, got " << tcu::formatArray(state.getIntVec4Access());
1672				result.fail(buf.str());
1673			}
1674			break;
1675		}
1676		case DATATYPE_UNSIGNED_INTEGER_VEC4:
1677		{
1678			bool				anyError = false;
1679			std::ostringstream	expectation;
1680
1681			for (int ndx = 0; ndx < 4; ++ndx)
1682			{
1683				const glw::GLuint refValueMin = roundGLfloatToNearestIntegerHalfDown<glw::GLuint>(expected[ndx]);
1684				const glw::GLuint refValueMax = roundGLfloatToNearestIntegerHalfUp<glw::GLuint>(expected[ndx]);
1685
1686				if (state.getUintVec4Access()[ndx] < refValueMin ||
1687					state.getUintVec4Access()[ndx] > refValueMax)
1688				{
1689					std::ostringstream buf;
1690
1691					if (ndx > 0)
1692						expectation << " ,";
1693
1694					if (refValueMin == refValueMax)
1695						buf << refValueMin;
1696					else
1697						buf << "[" << refValueMin << ", " << refValueMax << "]";
1698				}
1699			}
1700
1701			if (anyError)
1702			{
1703				std::ostringstream buf;
1704				buf << "Expected {" << expectation.str() << "}, got " << tcu::formatArray(state.getUintVec4Access());
1705				result.fail(buf.str());
1706			}
1707			break;
1708		}
1709
1710		default:
1711			DE_ASSERT(DE_FALSE);
1712			break;
1713	}
1714}
1715
1716void verifyPointer (tcu::ResultCollector& result, QueriedState& state, const void* expected)
1717{
1718	switch (state.getType())
1719	{
1720		case DATATYPE_POINTER:
1721		{
1722			if (state.getPtrAccess() != expected)
1723			{
1724				std::ostringstream buf;
1725				buf << "Expected " << expected << ", got " << state.getPtrAccess();
1726				result.fail(buf.str());
1727			}
1728			break;
1729		}
1730
1731		default:
1732			DE_ASSERT(DE_FALSE);
1733			break;
1734	}
1735}
1736
1737static float normalizeI32Float (deInt32 c)
1738{
1739	return de::max((float)c / float((1ul << 31) - 1u), -1.0f);
1740}
1741
1742void verifyNormalizedI32Vec4 (tcu::ResultCollector& result, QueriedState& state, const tcu::IVec4& expected)
1743{
1744	// \note: normalization precision is irrelevant for these tests, we can use very large thresholds
1745	const float			normalizationError	= 0.1f;
1746	const tcu::Vec4		reference			(normalizeI32Float(expected[0]),
1747											 normalizeI32Float(expected[1]),
1748											 normalizeI32Float(expected[2]),
1749											 normalizeI32Float(expected[3]));
1750	const tcu::Vec4		validHigh			(de::min( 1.0f, reference[0] + normalizationError),
1751											 de::min( 1.0f, reference[1] + normalizationError),
1752											 de::min( 1.0f, reference[2] + normalizationError),
1753											 de::min( 1.0f, reference[3] + normalizationError));
1754	const tcu::Vec4		validLow			(de::max(-1.0f, reference[0] - normalizationError),
1755											 de::max(-1.0f, reference[1] - normalizationError),
1756											 de::max(-1.0f, reference[2] - normalizationError),
1757											 de::max(-1.0f, reference[3] - normalizationError));
1758
1759	switch (state.getType())
1760	{
1761		case DATATYPE_FLOAT_VEC4:
1762		{
1763			bool				anyError = false;
1764			std::ostringstream	expectation;
1765
1766			for (int ndx = 0; ndx < 4; ++ndx)
1767			{
1768				if (state.getFloatVec4Access()[ndx] < validLow[ndx] ||
1769					state.getFloatVec4Access()[ndx] > validHigh[ndx])
1770				{
1771					std::ostringstream buf;
1772
1773					if (ndx > 0)
1774						expectation << " ,";
1775					buf << "[" << validLow[ndx] << ", " << validHigh[ndx] << "]";
1776				}
1777			}
1778
1779			if (anyError)
1780			{
1781				std::ostringstream buf;
1782				buf << "Expected {" << expectation.str() << "}, got " << tcu::formatArray(state.getFloatVec4Access());
1783				result.fail(buf.str());
1784			}
1785			break;
1786		}
1787		case DATATYPE_INTEGER_VEC4:
1788		{
1789			bool				anyError = false;
1790			std::ostringstream	expectation;
1791
1792			for (int ndx = 0; ndx < 4; ++ndx)
1793			{
1794				const glw::GLint refValueMin = roundGLfloatToNearestIntegerHalfDown<glw::GLint>(validHigh[ndx]);
1795				const glw::GLint refValueMax = roundGLfloatToNearestIntegerHalfUp<glw::GLint>(validLow[ndx]);
1796
1797				if (state.getIntVec4Access()[ndx] < refValueMin ||
1798					state.getIntVec4Access()[ndx] > refValueMax)
1799				{
1800					std::ostringstream buf;
1801
1802					if (ndx > 0)
1803						expectation << " ,";
1804
1805					if (refValueMin == refValueMax)
1806						buf << refValueMin;
1807					else
1808						buf << "[" << refValueMin << ", " << refValueMax << "]";
1809				}
1810			}
1811
1812			if (anyError)
1813			{
1814				std::ostringstream buf;
1815				buf << "Expected {" << expectation.str() << "}, got " << tcu::formatArray(state.getIntVec4Access());
1816				result.fail(buf.str());
1817			}
1818			break;
1819		}
1820
1821		default:
1822			DE_ASSERT(DE_FALSE);
1823			break;
1824	}
1825}
1826
1827// helpers
1828
1829void verifyStateBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, bool refValue, QueryType type)
1830{
1831	QueriedState state;
1832
1833	queryState(result, gl, type, target, state);
1834
1835	if (!state.isUndefined())
1836		verifyBoolean(result, state, refValue);
1837}
1838
1839void verifyStateInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int refValue, QueryType type)
1840{
1841	QueriedState state;
1842
1843	queryState(result, gl, type, target, state);
1844
1845	if (!state.isUndefined())
1846		verifyInteger(result, state, refValue);
1847}
1848
1849void verifyStateIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int minValue, QueryType type)
1850{
1851	QueriedState state;
1852
1853	queryState(result, gl, type, target, state);
1854
1855	if (!state.isUndefined())
1856		verifyIntegerMin(result, state, minValue);
1857}
1858
1859void verifyStateIntegerMax (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int maxValue, QueryType type)
1860{
1861	QueriedState state;
1862
1863	queryState(result, gl, type, target, state);
1864
1865	if (!state.isUndefined())
1866		verifyIntegerMax(result, state, maxValue);
1867}
1868
1869void verifyStateIntegerEqualToOther (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum other, QueryType type)
1870{
1871	QueriedState stateA;
1872	QueriedState stateB;
1873
1874	queryState(result, gl, type, target, stateA);
1875	queryState(result, gl, type, other, stateB);
1876
1877	if (stateA.isUndefined() || stateB.isUndefined())
1878		return;
1879
1880	switch (type)
1881	{
1882		case QUERY_BOOLEAN:
1883		{
1884			if (stateA.getBoolAccess() != stateB.getBoolAccess())
1885				result.fail("expected equal results");
1886			break;
1887		}
1888
1889		case QUERY_INTEGER:
1890		{
1891			if (stateA.getIntAccess() != stateB.getIntAccess())
1892				result.fail("expected equal results");
1893			break;
1894		}
1895
1896		case QUERY_INTEGER64:
1897		{
1898			if (stateA.getInt64Access() != stateB.getInt64Access())
1899				result.fail("expected equal results");
1900			break;
1901		}
1902
1903		case QUERY_FLOAT:
1904		{
1905			if (stateA.getFloatAccess() != stateB.getFloatAccess())
1906				result.fail("expected equal results");
1907			break;
1908		}
1909
1910		default:
1911			DE_ASSERT(DE_FALSE);
1912			break;
1913	}
1914}
1915
1916void verifyStateFloat (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float reference, QueryType type)
1917{
1918	QueriedState state;
1919
1920	queryState(result, gl, type, target, state);
1921
1922	if (!state.isUndefined())
1923		verifyFloat(result, state, reference);
1924}
1925
1926void verifyStateFloatMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float minValue, QueryType type)
1927{
1928	QueriedState state;
1929
1930	queryState(result, gl, type, target, state);
1931
1932	if (!state.isUndefined())
1933		verifyFloatMin(result, state, minValue);
1934}
1935
1936void verifyStateFloatMax (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, float maxValue, QueryType type)
1937{
1938	QueriedState state;
1939
1940	queryState(result, gl, type, target, state);
1941
1942	if (!state.isUndefined())
1943		verifyFloatMax(result, state, maxValue);
1944}
1945
1946void verifyStatePointer (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, const void* expected, QueryType type)
1947{
1948	QueriedState state;
1949
1950	queryPointerState(result, gl, type, target, state);
1951
1952	if (!state.isUndefined())
1953		verifyPointer(result, state, expected);
1954}
1955
1956void verifyStateIndexedBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, bool expected, QueryType type)
1957{
1958	QueriedState state;
1959
1960	queryIndexedState(result, gl, type, target, index, state);
1961
1962	if (!state.isUndefined())
1963		verifyBoolean(result, state, expected);
1964}
1965
1966void verifyStateIndexedBooleanVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, const tcu::BVec4& expected, QueryType type)
1967{
1968	QueriedState state;
1969
1970	queryIndexedState(result, gl, type, target, index, state);
1971
1972	if (!state.isUndefined())
1973		verifyBooleanVec4(result, state, expected);
1974}
1975
1976void verifyStateIndexedInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int expected, QueryType type)
1977{
1978	QueriedState state;
1979
1980	queryIndexedState(result, gl, type, target, index, state);
1981
1982	if (!state.isUndefined())
1983		verifyInteger(result, state, expected);
1984}
1985
1986void verifyStateIndexedIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int minValue, QueryType type)
1987{
1988	QueriedState state;
1989
1990	queryIndexedState(result, gl, type, target, index, state);
1991
1992	if (!state.isUndefined())
1993		verifyIntegerMin(result, state, minValue);
1994}
1995
1996void verifyStateAttributeInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int index, int expected, QueryType type)
1997{
1998	QueriedState state;
1999
2000	queryAttributeState(result, gl, type, target, index, state);
2001
2002	if (!state.isUndefined())
2003		verifyInteger(result, state, expected);
2004}
2005
2006void verifyStateFramebufferInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type)
2007{
2008	QueriedState state;
2009
2010	queryFramebufferState(result, gl, type, target, pname, state);
2011
2012	if (!state.isUndefined())
2013		verifyInteger(result, state, expected);
2014}
2015
2016void verifyStateFramebufferIntegerMin (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int minValue, QueryType type)
2017{
2018	QueriedState state;
2019
2020	queryFramebufferState(result, gl, type, target, pname, state);
2021
2022	if (!state.isUndefined())
2023		verifyIntegerMin(result, state, minValue);
2024}
2025
2026void verifyStateProgramInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint program, glw::GLenum pname, int expected, QueryType type)
2027{
2028	QueriedState state;
2029
2030	queryProgramState(result, gl, type, program, pname, state);
2031
2032	if (!state.isUndefined())
2033		verifyInteger(result, state, expected);
2034}
2035
2036void verifyStateProgramIntegerVec3 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint program, glw::GLenum pname, const tcu::IVec3& expected, QueryType type)
2037{
2038	QueriedState state;
2039
2040	queryProgramState(result, gl, type, program, pname, state);
2041
2042	if (!state.isUndefined())
2043		verifyIntegerVec3(result, state, expected);
2044}
2045
2046void verifyStatePipelineInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint pipeline, glw::GLenum pname, int expected, QueryType type)
2047{
2048	QueriedState state;
2049
2050	queryPipelineState(result, gl, type, pipeline, pname, state);
2051
2052	if (!state.isUndefined())
2053		verifyInteger(result, state, expected);
2054}
2055
2056void verifyStateTextureParamInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type)
2057{
2058	QueriedState state;
2059
2060	queryTextureParamState(result, gl, type, target, pname, state);
2061
2062	if (!state.isUndefined())
2063		verifyInteger(result, state, expected);
2064}
2065
2066void verifyStateTextureParamFloat (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, float expected, QueryType type)
2067{
2068	QueriedState state;
2069
2070	queryTextureParamState(result, gl, type, target, pname, state);
2071
2072	if (!state.isUndefined())
2073		verifyFloat(result, state, expected);
2074}
2075
2076void verifyStateTextureParamFloatVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::Vec4& expected, QueryType type)
2077{
2078	QueriedState state;
2079
2080	queryTextureParamState(result, gl, type, target, pname, state);
2081
2082	if (!state.isUndefined())
2083		verifyFloatVec4(result, state, expected);
2084}
2085
2086void verifyStateTextureParamNormalizedI32Vec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::IVec4& expected, QueryType type)
2087{
2088	QueriedState state;
2089
2090	queryTextureParamState(result, gl, type, target, pname, state);
2091
2092	if (!state.isUndefined())
2093		verifyNormalizedI32Vec4(result, state, expected);
2094}
2095
2096void verifyStateTextureParamIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::IVec4& expected, QueryType type)
2097{
2098	QueriedState state;
2099
2100	queryTextureParamState(result, gl, type, target, pname, state);
2101
2102	if (!state.isUndefined())
2103		verifyIntegerVec4(result, state, expected);
2104}
2105
2106void verifyStateTextureParamUnsignedIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, const tcu::UVec4& expected, QueryType type)
2107{
2108	QueriedState state;
2109
2110	queryTextureParamState(result, gl, type, target, pname, state);
2111
2112	if (!state.isUndefined())
2113		verifyUnsignedIntegerVec4(result, state, expected);
2114}
2115
2116void verifyStateTextureLevelInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int expected, QueryType type)
2117{
2118	QueriedState state;
2119
2120	queryTextureLevelState(result, gl, type, target, level, pname, state);
2121
2122	if (!state.isUndefined())
2123		verifyInteger(result, state, expected);
2124}
2125
2126void verifyStateObjectBoolean (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint handle, bool expected, QueryType type)
2127{
2128	QueriedState state;
2129
2130	queryObjectState(result, gl, type, handle, state);
2131
2132	if (!state.isUndefined())
2133		verifyBoolean(result, state, expected);
2134}
2135
2136void verifyStateQueryInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLenum target, glw::GLenum pname, int expected, QueryType type)
2137{
2138	QueriedState state;
2139
2140	queryQueryState(result, gl, type, target, pname, state);
2141
2142	if (!state.isUndefined())
2143		verifyInteger(result, state, expected);
2144}
2145
2146void verifyStateSamplerParamInteger (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, int expected, QueryType type)
2147{
2148	QueriedState state;
2149
2150	querySamplerState(result, gl, type, sampler, pname, state);
2151
2152	if (!state.isUndefined())
2153		verifyInteger(result, state, expected);
2154}
2155
2156void verifyStateSamplerParamFloat (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, float expected, QueryType type)
2157{
2158	QueriedState state;
2159
2160	querySamplerState(result, gl, type, sampler, pname, state);
2161
2162	if (!state.isUndefined())
2163		verifyFloat(result, state, expected);
2164}
2165
2166void verifyStateSamplerParamFloatVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::Vec4& expected, QueryType type)
2167{
2168	QueriedState state;
2169
2170	querySamplerState(result, gl, type, sampler, pname, state);
2171
2172	if (!state.isUndefined())
2173		verifyFloatVec4(result, state, expected);
2174}
2175
2176void verifyStateSamplerParamNormalizedI32Vec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::IVec4& expected, QueryType type)
2177{
2178	QueriedState state;
2179
2180	querySamplerState(result, gl, type, sampler, pname, state);
2181
2182	if (!state.isUndefined())
2183		verifyNormalizedI32Vec4(result, state, expected);
2184}
2185
2186void verifyStateSamplerParamIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::IVec4& expected, QueryType type)
2187{
2188	QueriedState state;
2189
2190	querySamplerState(result, gl, type, sampler, pname, state);
2191
2192	if (!state.isUndefined())
2193		verifyIntegerVec4(result, state, expected);
2194}
2195
2196void verifyStateSamplerParamUnsignedIntegerVec4 (tcu::ResultCollector& result, glu::CallLogWrapper& gl, glw::GLuint sampler, glw::GLenum pname, const tcu::UVec4& expected, QueryType type)
2197{
2198	QueriedState state;
2199
2200	querySamplerState(result, gl, type, sampler, pname, state);
2201
2202	if (!state.isUndefined())
2203		verifyUnsignedIntegerVec4(result, state, expected);
2204}
2205
2206} // StateQueryUtil
2207} // gls
2208} // deqp
2209