1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite
3e5c31af7Sopenharmony_ci * -----------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright (c) 2014-2016 The Khronos Group Inc.
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci */ /*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief
22e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci/**
25e5c31af7Sopenharmony_ci * \file  gl3cTransformFeedbackOverflowQueryTests.cpp
26e5c31af7Sopenharmony_ci * \brief Implements conformance tests for "Transform Feedback Overflow
27e5c31af7Sopenharmony_ci *        Query" functionality.
28e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/
29e5c31af7Sopenharmony_ci
30e5c31af7Sopenharmony_ci#include "gl3cTransformFeedbackOverflowQueryTests.hpp"
31e5c31af7Sopenharmony_ci
32e5c31af7Sopenharmony_ci#include "deMath.h"
33e5c31af7Sopenharmony_ci#include "deSharedPtr.hpp"
34e5c31af7Sopenharmony_ci
35e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp"
36e5c31af7Sopenharmony_ci#include "gluDefs.hpp"
37e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp"
38e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp"
39e5c31af7Sopenharmony_ci
40e5c31af7Sopenharmony_ci#include "tcuFuzzyImageCompare.hpp"
41e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp"
42e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp"
43e5c31af7Sopenharmony_ci#include "tcuSurface.hpp"
44e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp"
45e5c31af7Sopenharmony_ci
46e5c31af7Sopenharmony_ci#include "glw.h"
47e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
48e5c31af7Sopenharmony_ci
49e5c31af7Sopenharmony_cinamespace gl3cts
50e5c31af7Sopenharmony_ci{
51e5c31af7Sopenharmony_ci
52e5c31af7Sopenharmony_ci/*
53e5c31af7Sopenharmony_ci Base class of all test cases of the feature. Enforces the requirements below:
54e5c31af7Sopenharmony_ci
55e5c31af7Sopenharmony_ci * Check that the extension string is available.
56e5c31af7Sopenharmony_ci */
57e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryBaseTest : public deqp::TestCase
58e5c31af7Sopenharmony_ci{
59e5c31af7Sopenharmony_ciprotected:
60e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryBaseTest(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api,
61e5c31af7Sopenharmony_ci										   const char* name, const char* description)
62e5c31af7Sopenharmony_ci		: TestCase(context, name, description), m_api(api), m_max_vertex_streams(0)
63e5c31af7Sopenharmony_ci	{
64e5c31af7Sopenharmony_ci	}
65e5c31af7Sopenharmony_ci
66e5c31af7Sopenharmony_ci	/* Checks whether the feature is supported. */
67e5c31af7Sopenharmony_ci	bool featureSupported()
68e5c31af7Sopenharmony_ci	{
69e5c31af7Sopenharmony_ci		if (m_api == TransformFeedbackOverflowQueryTests::API_GL_ARB_transform_feedback_overflow_query)
70e5c31af7Sopenharmony_ci		{
71e5c31af7Sopenharmony_ci			glu::ContextType contextType = m_context.getRenderContext().getType();
72e5c31af7Sopenharmony_ci			if (m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback_overflow_query") ||
73e5c31af7Sopenharmony_ci				glu::contextSupports(contextType, glu::ApiType::core(4, 6)))
74e5c31af7Sopenharmony_ci			{
75e5c31af7Sopenharmony_ci				return true;
76e5c31af7Sopenharmony_ci			}
77e5c31af7Sopenharmony_ci		}
78e5c31af7Sopenharmony_ci		return false;
79e5c31af7Sopenharmony_ci	}
80e5c31af7Sopenharmony_ci
81e5c31af7Sopenharmony_ci	/* Checks whether transform_feedback2 is supported. */
82e5c31af7Sopenharmony_ci	bool supportsTransformFeedback2()
83e5c31af7Sopenharmony_ci	{
84e5c31af7Sopenharmony_ci		return (m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback2") ||
85e5c31af7Sopenharmony_ci				glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType(4, 0, glu::PROFILE_CORE)));
86e5c31af7Sopenharmony_ci	}
87e5c31af7Sopenharmony_ci
88e5c31af7Sopenharmony_ci	/* Checks whether transform_feedback3 is supported. */
89e5c31af7Sopenharmony_ci	bool supportsTransformFeedback3()
90e5c31af7Sopenharmony_ci	{
91e5c31af7Sopenharmony_ci		return (m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback3") ||
92e5c31af7Sopenharmony_ci				glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType(4, 0, glu::PROFILE_CORE)));
93e5c31af7Sopenharmony_ci	}
94e5c31af7Sopenharmony_ci
95e5c31af7Sopenharmony_ci	/* Checks whether gpu_shader5 is supported. */
96e5c31af7Sopenharmony_ci	bool supportsGpuShader5()
97e5c31af7Sopenharmony_ci	{
98e5c31af7Sopenharmony_ci		return (m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader5") ||
99e5c31af7Sopenharmony_ci				glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType(4, 0, glu::PROFILE_CORE)));
100e5c31af7Sopenharmony_ci	}
101e5c31af7Sopenharmony_ci
102e5c31af7Sopenharmony_ci	/* Checks whether conditional_render_inverted is supported. */
103e5c31af7Sopenharmony_ci	bool supportsConditionalRenderInverted()
104e5c31af7Sopenharmony_ci	{
105e5c31af7Sopenharmony_ci		return (m_context.getContextInfo().isExtensionSupported("GL_ARB_conditional_render_inverted") ||
106e5c31af7Sopenharmony_ci				glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType(4, 5, glu::PROFILE_CORE)));
107e5c31af7Sopenharmony_ci	}
108e5c31af7Sopenharmony_ci
109e5c31af7Sopenharmony_ci	/* Checks whether query_buffer_object are supported. */
110e5c31af7Sopenharmony_ci	bool supportsQueryBufferObject()
111e5c31af7Sopenharmony_ci	{
112e5c31af7Sopenharmony_ci		return (m_context.getContextInfo().isExtensionSupported("GL_ARB_query_buffer_object") ||
113e5c31af7Sopenharmony_ci				glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType(4, 4, glu::PROFILE_CORE)));
114e5c31af7Sopenharmony_ci	}
115e5c31af7Sopenharmony_ci
116e5c31af7Sopenharmony_ci	/* Returns the maximum number of vertex streams. */
117e5c31af7Sopenharmony_ci	GLuint getMaxVertexStreams() const
118e5c31af7Sopenharmony_ci	{
119e5c31af7Sopenharmony_ci		return m_max_vertex_streams;
120e5c31af7Sopenharmony_ci	}
121e5c31af7Sopenharmony_ci
122e5c31af7Sopenharmony_ci	/* Basic test init, child classes must call it. */
123e5c31af7Sopenharmony_ci	virtual void init()
124e5c31af7Sopenharmony_ci	{
125e5c31af7Sopenharmony_ci		if (!featureSupported())
126e5c31af7Sopenharmony_ci		{
127e5c31af7Sopenharmony_ci			throw tcu::NotSupportedError("Required transform_feedback_overflow_query extension is not supported");
128e5c31af7Sopenharmony_ci		}
129e5c31af7Sopenharmony_ci
130e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
131e5c31af7Sopenharmony_ci		{
132e5c31af7Sopenharmony_ci			m_max_vertex_streams = (GLuint)m_context.getContextInfo().getInt(GL_MAX_VERTEX_STREAMS);
133e5c31af7Sopenharmony_ci		}
134e5c31af7Sopenharmony_ci	}
135e5c31af7Sopenharmony_ci
136e5c31af7Sopenharmony_ciprotected:
137e5c31af7Sopenharmony_ci	const TransformFeedbackOverflowQueryTests::API m_api;
138e5c31af7Sopenharmony_ci
139e5c31af7Sopenharmony_ciprivate:
140e5c31af7Sopenharmony_ci	GLuint m_max_vertex_streams;
141e5c31af7Sopenharmony_ci};
142e5c31af7Sopenharmony_ci
143e5c31af7Sopenharmony_ci/*
144e5c31af7Sopenharmony_ci API Implementation Dependent State Test
145e5c31af7Sopenharmony_ci
146e5c31af7Sopenharmony_ci * Check that calling GetQueryiv with target TRANSFORM_FEEDBACK_OVERFLOW
147e5c31af7Sopenharmony_ci and pname QUERY_COUNTER_BITS returns a non-negative value without error.
148e5c31af7Sopenharmony_ci
149e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling
150e5c31af7Sopenharmony_ci GetQueryiv with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW and pname
151e5c31af7Sopenharmony_ci QUERY_COUNTER_BITS returns a non-negative value without error.
152e5c31af7Sopenharmony_ci */
153e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryImplDepState : public TransformFeedbackOverflowQueryBaseTest
154e5c31af7Sopenharmony_ci{
155e5c31af7Sopenharmony_cipublic:
156e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryImplDepState(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api,
157e5c31af7Sopenharmony_ci											   const char* name)
158e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQueryBaseTest(
159e5c31af7Sopenharmony_ci			  context, api, name,
160e5c31af7Sopenharmony_ci			  "Tests whether the implementation dependent state defined by the feature matches the requirements.")
161e5c31af7Sopenharmony_ci	{
162e5c31af7Sopenharmony_ci	}
163e5c31af7Sopenharmony_ci
164e5c31af7Sopenharmony_ci	/* Test case iterate function. Contains the actual test case logic. */
165e5c31af7Sopenharmony_ci	IterateResult iterate()
166e5c31af7Sopenharmony_ci	{
167e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
168e5c31af7Sopenharmony_ci		GLint				  counterBits;
169e5c31af7Sopenharmony_ci
170e5c31af7Sopenharmony_ci		gl.getQueryiv(GL_TRANSFORM_FEEDBACK_OVERFLOW, GL_QUERY_COUNTER_BITS, &counterBits);
171e5c31af7Sopenharmony_ci		if (counterBits < 0)
172e5c31af7Sopenharmony_ci		{
173e5c31af7Sopenharmony_ci			TCU_FAIL("Value of QUERY_COUNTER_BITS for query target TRANSFORM_FEEDBACK_OVERFLOW is invalid");
174e5c31af7Sopenharmony_ci		}
175e5c31af7Sopenharmony_ci
176e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
177e5c31af7Sopenharmony_ci		{
178e5c31af7Sopenharmony_ci			gl.getQueryiv(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, GL_QUERY_COUNTER_BITS, &counterBits);
179e5c31af7Sopenharmony_ci			if (counterBits < 0)
180e5c31af7Sopenharmony_ci			{
181e5c31af7Sopenharmony_ci				TCU_FAIL("Value of QUERY_COUNTER_BITS for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW is invalid");
182e5c31af7Sopenharmony_ci			}
183e5c31af7Sopenharmony_ci		}
184e5c31af7Sopenharmony_ci
185e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
186e5c31af7Sopenharmony_ci
187e5c31af7Sopenharmony_ci		return STOP;
188e5c31af7Sopenharmony_ci	}
189e5c31af7Sopenharmony_ci};
190e5c31af7Sopenharmony_ci
191e5c31af7Sopenharmony_ci/*
192e5c31af7Sopenharmony_ci Base class for all test cases of the feature that verify newly introduced context state.
193e5c31af7Sopenharmony_ci */
194e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryContextStateBase : public TransformFeedbackOverflowQueryBaseTest
195e5c31af7Sopenharmony_ci{
196e5c31af7Sopenharmony_ciprotected:
197e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryContextStateBase(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api,
198e5c31af7Sopenharmony_ci												   const char* name, const char* description)
199e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQueryBaseTest(context, api, name, description)
200e5c31af7Sopenharmony_ci	{
201e5c31af7Sopenharmony_ci	}
202e5c31af7Sopenharmony_ci
203e5c31af7Sopenharmony_ci	/* Returns whether CURRENT_QUERY state for the specified target and index matches the given value. */
204e5c31af7Sopenharmony_ci	bool verifyCurrentQueryState(GLenum target, GLuint index, GLuint value)
205e5c31af7Sopenharmony_ci	{
206e5c31af7Sopenharmony_ci		const glw::Functions& gl	   = m_context.getRenderContext().getFunctions();
207e5c31af7Sopenharmony_ci		GLint				  expected = (GLint)value;
208e5c31af7Sopenharmony_ci		GLint				  actual;
209e5c31af7Sopenharmony_ci
210e5c31af7Sopenharmony_ci		// Use GetQueryIndexediv by default
211e5c31af7Sopenharmony_ci		gl.getQueryIndexediv(target, index, GL_CURRENT_QUERY, &actual);
212e5c31af7Sopenharmony_ci		if (actual != expected)
213e5c31af7Sopenharmony_ci		{
214e5c31af7Sopenharmony_ci			return false;
215e5c31af7Sopenharmony_ci		}
216e5c31af7Sopenharmony_ci
217e5c31af7Sopenharmony_ci		if (index == 0)
218e5c31af7Sopenharmony_ci		{
219e5c31af7Sopenharmony_ci			// If index is zero then GetQueryiv should also return the expected value
220e5c31af7Sopenharmony_ci			gl.getQueryiv(target, GL_CURRENT_QUERY, &actual);
221e5c31af7Sopenharmony_ci			if (actual != expected)
222e5c31af7Sopenharmony_ci			{
223e5c31af7Sopenharmony_ci				return false;
224e5c31af7Sopenharmony_ci			}
225e5c31af7Sopenharmony_ci		}
226e5c31af7Sopenharmony_ci
227e5c31af7Sopenharmony_ci		return true;
228e5c31af7Sopenharmony_ci	}
229e5c31af7Sopenharmony_ci};
230e5c31af7Sopenharmony_ci
231e5c31af7Sopenharmony_ci/*
232e5c31af7Sopenharmony_ci API Default Context State Test
233e5c31af7Sopenharmony_ci
234e5c31af7Sopenharmony_ci * Check that calling GetQueryiv with target TRANSFORM_FEEDBACK_OVERFLOW
235e5c31af7Sopenharmony_ci and pname CURRENT_QUERY returns zero by default.
236e5c31af7Sopenharmony_ci
237e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling
238e5c31af7Sopenharmony_ci GetQueryIndexediv with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW and
239e5c31af7Sopenharmony_ci pname CURRENT_QUERY returns zero for any index between zero and MAX_-
240e5c31af7Sopenharmony_ci VERTEX_STREAMS.
241e5c31af7Sopenharmony_ci */
242e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryDefaultState : public TransformFeedbackOverflowQueryContextStateBase
243e5c31af7Sopenharmony_ci{
244e5c31af7Sopenharmony_cipublic:
245e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryDefaultState(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api,
246e5c31af7Sopenharmony_ci											   const char* name)
247e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQueryContextStateBase(
248e5c31af7Sopenharmony_ci			  context, api, name,
249e5c31af7Sopenharmony_ci			  "Tests whether the new context state defined by the feature has the expected default values.")
250e5c31af7Sopenharmony_ci	{
251e5c31af7Sopenharmony_ci	}
252e5c31af7Sopenharmony_ci
253e5c31af7Sopenharmony_ci	/* Test case iterate function. Contains the actual test case logic. */
254e5c31af7Sopenharmony_ci	IterateResult iterate()
255e5c31af7Sopenharmony_ci	{
256e5c31af7Sopenharmony_ci		if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, 0))
257e5c31af7Sopenharmony_ci		{
258e5c31af7Sopenharmony_ci			TCU_FAIL("Default value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_OVERFLOW is non-zero");
259e5c31af7Sopenharmony_ci		}
260e5c31af7Sopenharmony_ci
261e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
262e5c31af7Sopenharmony_ci		{
263e5c31af7Sopenharmony_ci			for (GLuint i = 0; i < getMaxVertexStreams(); ++i)
264e5c31af7Sopenharmony_ci			{
265e5c31af7Sopenharmony_ci				if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, 0, 0))
266e5c31af7Sopenharmony_ci				{
267e5c31af7Sopenharmony_ci					TCU_FAIL("Default value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW "
268e5c31af7Sopenharmony_ci							 "is non-zero");
269e5c31af7Sopenharmony_ci				}
270e5c31af7Sopenharmony_ci			}
271e5c31af7Sopenharmony_ci		}
272e5c31af7Sopenharmony_ci
273e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
274e5c31af7Sopenharmony_ci
275e5c31af7Sopenharmony_ci		return STOP;
276e5c31af7Sopenharmony_ci	}
277e5c31af7Sopenharmony_ci};
278e5c31af7Sopenharmony_ci
279e5c31af7Sopenharmony_ci/*
280e5c31af7Sopenharmony_ci API Context State Update Test
281e5c31af7Sopenharmony_ci
282e5c31af7Sopenharmony_ci * Check that after a successful call to BeginQuery with target TRANSFORM_-
283e5c31af7Sopenharmony_ci FEEDBACK_OVERFLOW_ARB calling GetQueryiv with the same target and with
284e5c31af7Sopenharmony_ci pname CURRENT_QUERY returns the name of the query previously passed to
285e5c31af7Sopenharmony_ci BeginQuery. Also check that after calling EndQuery with the same target
286e5c31af7Sopenharmony_ci GetQueryiv returns zero for the same parameters.
287e5c31af7Sopenharmony_ci
288e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that after a
289e5c31af7Sopenharmony_ci successful call to BeginQueryIndexed with target TRANSFORM_FEEDBACK_-
290e5c31af7Sopenharmony_ci STREAM_OVERFLOW_ARB calling GetQueryIndexediv with the same target and
291e5c31af7Sopenharmony_ci with pname CURRENT_QUERY returns the name of the query previously passed
292e5c31af7Sopenharmony_ci to BeginQueryIndexed if the index parameters match and otherwise it
293e5c31af7Sopenharmony_ci returns zero. Also check that after calling EndQueryIndexed with the
294e5c31af7Sopenharmony_ci same target and index GetQueryIndexediv returns zero for the same
295e5c31af7Sopenharmony_ci parameters for all indices. Indices used should be between zero and
296e5c31af7Sopenharmony_ci MAX_VERTEX_STREAMS.
297e5c31af7Sopenharmony_ci */
298e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryStateUpdate : public TransformFeedbackOverflowQueryContextStateBase
299e5c31af7Sopenharmony_ci{
300e5c31af7Sopenharmony_cipublic:
301e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryStateUpdate(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api,
302e5c31af7Sopenharmony_ci											  const char* name)
303e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQueryContextStateBase(
304e5c31af7Sopenharmony_ci			  context, api, name,
305e5c31af7Sopenharmony_ci			  "Tests whether the new context state defined by the feature is correctly updated after a successful "
306e5c31af7Sopenharmony_ci			  "call to {Begin|End}Query[Indexed] if the target of the query is one of the newly introduced ones.")
307e5c31af7Sopenharmony_ci		, m_overflow_query(0)
308e5c31af7Sopenharmony_ci		, m_stream_overflow_query(0)
309e5c31af7Sopenharmony_ci	{
310e5c31af7Sopenharmony_ci	}
311e5c31af7Sopenharmony_ci
312e5c31af7Sopenharmony_ci	/* Test case init. */
313e5c31af7Sopenharmony_ci	virtual void init()
314e5c31af7Sopenharmony_ci	{
315e5c31af7Sopenharmony_ci		TransformFeedbackOverflowQueryContextStateBase::init();
316e5c31af7Sopenharmony_ci
317e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
318e5c31af7Sopenharmony_ci
319e5c31af7Sopenharmony_ci		gl.genQueries(1, &m_overflow_query);
320e5c31af7Sopenharmony_ci		gl.genQueries(1, &m_stream_overflow_query);
321e5c31af7Sopenharmony_ci	}
322e5c31af7Sopenharmony_ci
323e5c31af7Sopenharmony_ci	/* Test case deinit */
324e5c31af7Sopenharmony_ci	virtual void deinit()
325e5c31af7Sopenharmony_ci	{
326e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
327e5c31af7Sopenharmony_ci
328e5c31af7Sopenharmony_ci		gl.deleteQueries(1, &m_overflow_query);
329e5c31af7Sopenharmony_ci		gl.deleteQueries(1, &m_stream_overflow_query);
330e5c31af7Sopenharmony_ci
331e5c31af7Sopenharmony_ci		TransformFeedbackOverflowQueryContextStateBase::deinit();
332e5c31af7Sopenharmony_ci	}
333e5c31af7Sopenharmony_ci
334e5c31af7Sopenharmony_ci	/* Test case iterate function. Contains the actual test case logic. */
335e5c31af7Sopenharmony_ci	IterateResult iterate()
336e5c31af7Sopenharmony_ci	{
337e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
338e5c31af7Sopenharmony_ci
339e5c31af7Sopenharmony_ci		// Call BeginQuery
340e5c31af7Sopenharmony_ci		gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_overflow_query);
341e5c31af7Sopenharmony_ci
342e5c31af7Sopenharmony_ci		// Verify that CURRENT_QUERY is set to the name of the query
343e5c31af7Sopenharmony_ci		if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, m_overflow_query))
344e5c31af7Sopenharmony_ci		{
345e5c31af7Sopenharmony_ci			TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_OVERFLOW is not updated properly "
346e5c31af7Sopenharmony_ci					 "after a call to BeginQuery");
347e5c31af7Sopenharmony_ci		}
348e5c31af7Sopenharmony_ci
349e5c31af7Sopenharmony_ci		// Call EndQuery
350e5c31af7Sopenharmony_ci		gl.endQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW);
351e5c31af7Sopenharmony_ci
352e5c31af7Sopenharmony_ci		// Verify that CURRENT_QUERY is reset to zero
353e5c31af7Sopenharmony_ci		if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, 0))
354e5c31af7Sopenharmony_ci		{
355e5c31af7Sopenharmony_ci			TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_OVERFLOW is not reset properly "
356e5c31af7Sopenharmony_ci					 "after a call to EndQuery");
357e5c31af7Sopenharmony_ci		}
358e5c31af7Sopenharmony_ci
359e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
360e5c31af7Sopenharmony_ci		{
361e5c31af7Sopenharmony_ci			for (GLuint i = 0; i < getMaxVertexStreams(); ++i)
362e5c31af7Sopenharmony_ci			{
363e5c31af7Sopenharmony_ci				// Call BeginQueryIndexed with specified index
364e5c31af7Sopenharmony_ci				gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i, m_stream_overflow_query);
365e5c31af7Sopenharmony_ci
366e5c31af7Sopenharmony_ci				// Verify that CURRENT_QUERY is set to the name of the query for the specified index, but remains zero for other indices
367e5c31af7Sopenharmony_ci				for (GLuint j = 0; j < getMaxVertexStreams(); ++j)
368e5c31af7Sopenharmony_ci				{
369e5c31af7Sopenharmony_ci					if (i == j)
370e5c31af7Sopenharmony_ci					{
371e5c31af7Sopenharmony_ci						if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, j, m_stream_overflow_query))
372e5c31af7Sopenharmony_ci						{
373e5c31af7Sopenharmony_ci							TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW "
374e5c31af7Sopenharmony_ci									 "is not updated properly after a call to BeginQueryIndexed");
375e5c31af7Sopenharmony_ci						}
376e5c31af7Sopenharmony_ci					}
377e5c31af7Sopenharmony_ci					else
378e5c31af7Sopenharmony_ci					{
379e5c31af7Sopenharmony_ci						if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, j, 0))
380e5c31af7Sopenharmony_ci						{
381e5c31af7Sopenharmony_ci							TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW "
382e5c31af7Sopenharmony_ci									 "is incorrectly updated for an unrelated vertex stream"
383e5c31af7Sopenharmony_ci									 "index after a call to BeginQueryIndexed");
384e5c31af7Sopenharmony_ci						}
385e5c31af7Sopenharmony_ci					}
386e5c31af7Sopenharmony_ci				}
387e5c31af7Sopenharmony_ci
388e5c31af7Sopenharmony_ci				// Call EndQueryIndexed with specified index
389e5c31af7Sopenharmony_ci				gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i);
390e5c31af7Sopenharmony_ci
391e5c31af7Sopenharmony_ci				// Verify that CURRENT_QUERY is reset to zero for the specified index and still remains zero for other indices
392e5c31af7Sopenharmony_ci				for (GLuint j = 0; j < getMaxVertexStreams(); ++j)
393e5c31af7Sopenharmony_ci				{
394e5c31af7Sopenharmony_ci					if (i == j)
395e5c31af7Sopenharmony_ci					{
396e5c31af7Sopenharmony_ci						if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, j, 0))
397e5c31af7Sopenharmony_ci						{
398e5c31af7Sopenharmony_ci							TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW "
399e5c31af7Sopenharmony_ci									 "is not reset properly after a call to EndQueryIndexed");
400e5c31af7Sopenharmony_ci						}
401e5c31af7Sopenharmony_ci					}
402e5c31af7Sopenharmony_ci					else
403e5c31af7Sopenharmony_ci					{
404e5c31af7Sopenharmony_ci						if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, j, 0))
405e5c31af7Sopenharmony_ci						{
406e5c31af7Sopenharmony_ci							TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW "
407e5c31af7Sopenharmony_ci									 "is incorrectly updated for an unrelated vertex stream"
408e5c31af7Sopenharmony_ci									 "index after a call to EndQueryIndexed");
409e5c31af7Sopenharmony_ci						}
410e5c31af7Sopenharmony_ci					}
411e5c31af7Sopenharmony_ci				}
412e5c31af7Sopenharmony_ci			}
413e5c31af7Sopenharmony_ci		}
414e5c31af7Sopenharmony_ci
415e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
416e5c31af7Sopenharmony_ci
417e5c31af7Sopenharmony_ci		return STOP;
418e5c31af7Sopenharmony_ci	}
419e5c31af7Sopenharmony_ci
420e5c31af7Sopenharmony_ciprotected:
421e5c31af7Sopenharmony_ci	GLuint m_overflow_query;
422e5c31af7Sopenharmony_ci	GLuint m_stream_overflow_query;
423e5c31af7Sopenharmony_ci};
424e5c31af7Sopenharmony_ci
425e5c31af7Sopenharmony_ci/*
426e5c31af7Sopenharmony_ci Base class for all test cases of the feature that verify various error scenarios.
427e5c31af7Sopenharmony_ci */
428e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryErrorBase : public TransformFeedbackOverflowQueryBaseTest
429e5c31af7Sopenharmony_ci{
430e5c31af7Sopenharmony_ciprotected:
431e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryErrorBase(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api,
432e5c31af7Sopenharmony_ci											const char* name, const char* description)
433e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQueryBaseTest(context, api, name, description), m_case_name(0)
434e5c31af7Sopenharmony_ci	{
435e5c31af7Sopenharmony_ci	}
436e5c31af7Sopenharmony_ci
437e5c31af7Sopenharmony_ci	/* Starts a new error scenario sub-test with the given name. The name is used in error messages if the sub-test fails. */
438e5c31af7Sopenharmony_ci	void startTest(const char* caseName)
439e5c31af7Sopenharmony_ci	{
440e5c31af7Sopenharmony_ci		m_case_name = caseName;
441e5c31af7Sopenharmony_ci	}
442e5c31af7Sopenharmony_ci
443e5c31af7Sopenharmony_ci	/* Verifies whether the actually generated error matches that of the expected one. If not then it triggers the failure
444e5c31af7Sopenharmony_ci	 of the test case with the sub-case name used as the failure message. */
445e5c31af7Sopenharmony_ci	void verifyError(GLenum expectedError)
446e5c31af7Sopenharmony_ci	{
447e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
448e5c31af7Sopenharmony_ci
449e5c31af7Sopenharmony_ci		GLenum actualError = gl.getError();
450e5c31af7Sopenharmony_ci
451e5c31af7Sopenharmony_ci		if (actualError != expectedError)
452e5c31af7Sopenharmony_ci		{
453e5c31af7Sopenharmony_ci			TCU_FAIL(m_case_name);
454e5c31af7Sopenharmony_ci		}
455e5c31af7Sopenharmony_ci	}
456e5c31af7Sopenharmony_ci
457e5c31af7Sopenharmony_ciprivate:
458e5c31af7Sopenharmony_ci	const char* m_case_name;
459e5c31af7Sopenharmony_ci};
460e5c31af7Sopenharmony_ci
461e5c31af7Sopenharmony_ci/*
462e5c31af7Sopenharmony_ci API Invalid Index Error Test
463e5c31af7Sopenharmony_ci
464e5c31af7Sopenharmony_ci * Check that calling GetQueryIndexediv with target TRANSFORM_FEEDBACK_-
465e5c31af7Sopenharmony_ci OVERFLOW_ARB and a non-zero index generates an INVALID_VALUE error.
466e5c31af7Sopenharmony_ci
467e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling
468e5c31af7Sopenharmony_ci GetQueryIndexediv with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW
469e5c31af7Sopenharmony_ci and an index greater than or equal to MAX_VERTEX_STREAMS generates an
470e5c31af7Sopenharmony_ci INVALID_VALUE error.
471e5c31af7Sopenharmony_ci
472e5c31af7Sopenharmony_ci * Check that calling BeginQueryIndexed with target TRANSFORM_FEEDBACK_-
473e5c31af7Sopenharmony_ci OVERFLOW_ARB and a non-zero index generates an INVALID_VALUE error.
474e5c31af7Sopenharmony_ci
475e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling
476e5c31af7Sopenharmony_ci BeginQueryIndexed with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW
477e5c31af7Sopenharmony_ci and an index greater than or equal to MAX_VERTEX_STREAMS generates an
478e5c31af7Sopenharmony_ci INVALID_VALUE error.
479e5c31af7Sopenharmony_ci */
480e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryErrorInvalidIndex : public TransformFeedbackOverflowQueryErrorBase
481e5c31af7Sopenharmony_ci{
482e5c31af7Sopenharmony_cipublic:
483e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryErrorInvalidIndex(deqp::Context&							 context,
484e5c31af7Sopenharmony_ci													TransformFeedbackOverflowQueryTests::API api, const char* name)
485e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQueryErrorBase(
486e5c31af7Sopenharmony_ci			  context, api, name, "Verifies whether an INVALID_VALUE error is properly generated if GetQueryIndexediv "
487e5c31af7Sopenharmony_ci								  "or BeginQueryIndexed is called "
488e5c31af7Sopenharmony_ci								  "with an invalid index when using the new targets introduced by the feature.")
489e5c31af7Sopenharmony_ci		, m_query(0)
490e5c31af7Sopenharmony_ci	{
491e5c31af7Sopenharmony_ci	}
492e5c31af7Sopenharmony_ci
493e5c31af7Sopenharmony_ci	/* Test case init. */
494e5c31af7Sopenharmony_ci	virtual void init()
495e5c31af7Sopenharmony_ci	{
496e5c31af7Sopenharmony_ci		TransformFeedbackOverflowQueryErrorBase::init();
497e5c31af7Sopenharmony_ci
498e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
499e5c31af7Sopenharmony_ci
500e5c31af7Sopenharmony_ci		gl.genQueries(1, &m_query);
501e5c31af7Sopenharmony_ci	}
502e5c31af7Sopenharmony_ci
503e5c31af7Sopenharmony_ci	/* Test case deinit */
504e5c31af7Sopenharmony_ci	virtual void deinit()
505e5c31af7Sopenharmony_ci	{
506e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
507e5c31af7Sopenharmony_ci
508e5c31af7Sopenharmony_ci		gl.deleteQueries(1, &m_query);
509e5c31af7Sopenharmony_ci
510e5c31af7Sopenharmony_ci		TransformFeedbackOverflowQueryErrorBase::deinit();
511e5c31af7Sopenharmony_ci	}
512e5c31af7Sopenharmony_ci
513e5c31af7Sopenharmony_ci	/* Test case iterate function. Contains the actual test case logic. */
514e5c31af7Sopenharmony_ci	IterateResult iterate()
515e5c31af7Sopenharmony_ci	{
516e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
517e5c31af7Sopenharmony_ci		GLint				  value;
518e5c31af7Sopenharmony_ci
519e5c31af7Sopenharmony_ci		startTest("GetQueryIndexediv must generate INVALID_VALUE if <target> is "
520e5c31af7Sopenharmony_ci				  "TRANSFORM_FEEDBACK_OVERFLOW and <index> is non-zero.");
521e5c31af7Sopenharmony_ci
522e5c31af7Sopenharmony_ci		for (GLuint i = 1; i < getMaxVertexStreams(); ++i)
523e5c31af7Sopenharmony_ci		{
524e5c31af7Sopenharmony_ci			gl.getQueryIndexediv(GL_TRANSFORM_FEEDBACK_OVERFLOW, i, GL_CURRENT_QUERY, &value);
525e5c31af7Sopenharmony_ci			verifyError(GL_INVALID_VALUE);
526e5c31af7Sopenharmony_ci		}
527e5c31af7Sopenharmony_ci
528e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
529e5c31af7Sopenharmony_ci		{
530e5c31af7Sopenharmony_ci			startTest("GetQueryIndexediv must generate INVALID_VALUE if <target> is "
531e5c31af7Sopenharmony_ci					  "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and <index> is greater "
532e5c31af7Sopenharmony_ci					  "than or equal to MAX_VERTEX_STREAMS.");
533e5c31af7Sopenharmony_ci
534e5c31af7Sopenharmony_ci			for (GLuint i = getMaxVertexStreams(); i < getMaxVertexStreams() + 4; ++i)
535e5c31af7Sopenharmony_ci			{
536e5c31af7Sopenharmony_ci				gl.getQueryIndexediv(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i, GL_CURRENT_QUERY, &value);
537e5c31af7Sopenharmony_ci				verifyError(GL_INVALID_VALUE);
538e5c31af7Sopenharmony_ci			}
539e5c31af7Sopenharmony_ci		}
540e5c31af7Sopenharmony_ci
541e5c31af7Sopenharmony_ci		startTest("BeginQueryIndexed must generate INVALID_VALUE if <target> is "
542e5c31af7Sopenharmony_ci				  "TRANSFORM_FEEDBACK_OVERFLOW and <index> is non-zero.");
543e5c31af7Sopenharmony_ci
544e5c31af7Sopenharmony_ci		for (GLuint i = 1; i < getMaxVertexStreams(); ++i)
545e5c31af7Sopenharmony_ci		{
546e5c31af7Sopenharmony_ci			gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_OVERFLOW, i, m_query);
547e5c31af7Sopenharmony_ci			verifyError(GL_INVALID_VALUE);
548e5c31af7Sopenharmony_ci		}
549e5c31af7Sopenharmony_ci
550e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
551e5c31af7Sopenharmony_ci		{
552e5c31af7Sopenharmony_ci			startTest("BeginQueryIndexed must generate INVALID_VALUE if <target> is "
553e5c31af7Sopenharmony_ci					  "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and <index> is greater "
554e5c31af7Sopenharmony_ci					  "than or equal to MAX_VERTEX_STREAMS.");
555e5c31af7Sopenharmony_ci
556e5c31af7Sopenharmony_ci			for (GLuint i = getMaxVertexStreams(); i < getMaxVertexStreams() + 4; ++i)
557e5c31af7Sopenharmony_ci			{
558e5c31af7Sopenharmony_ci				gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i, m_query);
559e5c31af7Sopenharmony_ci				verifyError(GL_INVALID_VALUE);
560e5c31af7Sopenharmony_ci			}
561e5c31af7Sopenharmony_ci		}
562e5c31af7Sopenharmony_ci
563e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
564e5c31af7Sopenharmony_ci
565e5c31af7Sopenharmony_ci		return STOP;
566e5c31af7Sopenharmony_ci	}
567e5c31af7Sopenharmony_ci
568e5c31af7Sopenharmony_ciprotected:
569e5c31af7Sopenharmony_ci	GLuint m_query;
570e5c31af7Sopenharmony_ci};
571e5c31af7Sopenharmony_ci
572e5c31af7Sopenharmony_ci/*
573e5c31af7Sopenharmony_ci API Already Active Error Test
574e5c31af7Sopenharmony_ci
575e5c31af7Sopenharmony_ci * Check that calling BeginQuery with target TRANSFORM_FEEDBACK_OVERFLOW
576e5c31af7Sopenharmony_ci generates an INVALID_OPERATION error if there is already an active
577e5c31af7Sopenharmony_ci query for TRANSFORM_FEEDBACK_OVERFLOW.
578e5c31af7Sopenharmony_ci
579e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling
580e5c31af7Sopenharmony_ci BeginQueryIndexed with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW
581e5c31af7Sopenharmony_ci generates an INVALID_OPERATION error if there is already an active
582e5c31af7Sopenharmony_ci query for TRANSFORM_FEEDBACK_STREAM_OVERFLOW for the specified
583e5c31af7Sopenharmony_ci index.
584e5c31af7Sopenharmony_ci
585e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling
586e5c31af7Sopenharmony_ci BeginQueryIndexed with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW
587e5c31af7Sopenharmony_ci generates an INVALID_OPERATION error if the specified query is already
588e5c31af7Sopenharmony_ci active on another TRANSFORM_FEEDBACK_STREAM_OVERFLOW target with
589e5c31af7Sopenharmony_ci a different index.
590e5c31af7Sopenharmony_ci */
591e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryErrorAlreadyActive : public TransformFeedbackOverflowQueryErrorBase
592e5c31af7Sopenharmony_ci{
593e5c31af7Sopenharmony_cipublic:
594e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryErrorAlreadyActive(deqp::Context&							  context,
595e5c31af7Sopenharmony_ci													 TransformFeedbackOverflowQueryTests::API api, const char* name)
596e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQueryErrorBase(context, api, name,
597e5c31af7Sopenharmony_ci												  "Verifies whether an INVALID_OPERATION error is properly generated "
598e5c31af7Sopenharmony_ci												  "if BeginQuery[Indexed] is used to try to start "
599e5c31af7Sopenharmony_ci												  "a query on an index that has already a query active, or the query "
600e5c31af7Sopenharmony_ci												  "object itself is active on another index.")
601e5c31af7Sopenharmony_ci		, m_query(0)
602e5c31af7Sopenharmony_ci		, m_active_overflow_query(0)
603e5c31af7Sopenharmony_ci		, m_active_stream_overflow_query(0)
604e5c31af7Sopenharmony_ci		, m_active_query_stream_index(0)
605e5c31af7Sopenharmony_ci	{
606e5c31af7Sopenharmony_ci	}
607e5c31af7Sopenharmony_ci
608e5c31af7Sopenharmony_ci	/* Test case init. */
609e5c31af7Sopenharmony_ci	virtual void init()
610e5c31af7Sopenharmony_ci	{
611e5c31af7Sopenharmony_ci		TransformFeedbackOverflowQueryErrorBase::init();
612e5c31af7Sopenharmony_ci
613e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
614e5c31af7Sopenharmony_ci
615e5c31af7Sopenharmony_ci		gl.genQueries(1, &m_query);
616e5c31af7Sopenharmony_ci
617e5c31af7Sopenharmony_ci		gl.genQueries(1, &m_active_overflow_query);
618e5c31af7Sopenharmony_ci		gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_active_overflow_query);
619e5c31af7Sopenharmony_ci
620e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
621e5c31af7Sopenharmony_ci		{
622e5c31af7Sopenharmony_ci			gl.genQueries(1, &m_active_stream_overflow_query);
623e5c31af7Sopenharmony_ci			m_active_query_stream_index = 2;
624e5c31af7Sopenharmony_ci			gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_query_stream_index,
625e5c31af7Sopenharmony_ci								 m_active_stream_overflow_query);
626e5c31af7Sopenharmony_ci		}
627e5c31af7Sopenharmony_ci	}
628e5c31af7Sopenharmony_ci
629e5c31af7Sopenharmony_ci	/* Test case deinit */
630e5c31af7Sopenharmony_ci	virtual void deinit()
631e5c31af7Sopenharmony_ci	{
632e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
633e5c31af7Sopenharmony_ci
634e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
635e5c31af7Sopenharmony_ci		{
636e5c31af7Sopenharmony_ci			gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_query_stream_index);
637e5c31af7Sopenharmony_ci			gl.deleteQueries(1, &m_active_stream_overflow_query);
638e5c31af7Sopenharmony_ci		}
639e5c31af7Sopenharmony_ci
640e5c31af7Sopenharmony_ci		gl.endQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW);
641e5c31af7Sopenharmony_ci		gl.deleteQueries(1, &m_active_overflow_query);
642e5c31af7Sopenharmony_ci
643e5c31af7Sopenharmony_ci		gl.deleteQueries(1, &m_query);
644e5c31af7Sopenharmony_ci
645e5c31af7Sopenharmony_ci		TransformFeedbackOverflowQueryErrorBase::deinit();
646e5c31af7Sopenharmony_ci	}
647e5c31af7Sopenharmony_ci
648e5c31af7Sopenharmony_ci	/* Test case iterate function. Contains the actual test case logic. */
649e5c31af7Sopenharmony_ci	IterateResult iterate()
650e5c31af7Sopenharmony_ci	{
651e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
652e5c31af7Sopenharmony_ci
653e5c31af7Sopenharmony_ci		startTest("BeginQuery[Indexed] must generate INVALID_OPERATION if <target> is "
654e5c31af7Sopenharmony_ci				  "TRANSFORM_FEEDBACK_OVERFLOW and there is already an active "
655e5c31af7Sopenharmony_ci				  "query for TRANSFORM_FEEDBACK_ARB.");
656e5c31af7Sopenharmony_ci
657e5c31af7Sopenharmony_ci		gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_query);
658e5c31af7Sopenharmony_ci		verifyError(GL_INVALID_OPERATION);
659e5c31af7Sopenharmony_ci		gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, m_query);
660e5c31af7Sopenharmony_ci		verifyError(GL_INVALID_OPERATION);
661e5c31af7Sopenharmony_ci
662e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
663e5c31af7Sopenharmony_ci		{
664e5c31af7Sopenharmony_ci			startTest("BeginQueryIndexed must generate INVALID_OPERATION if <target> is "
665e5c31af7Sopenharmony_ci					  "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and there is already an active "
666e5c31af7Sopenharmony_ci					  "query for TRANSFORM_FEEDBACK_STREAM_OVERFLOW for the specified index.");
667e5c31af7Sopenharmony_ci
668e5c31af7Sopenharmony_ci			gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_query_stream_index, m_query);
669e5c31af7Sopenharmony_ci			verifyError(GL_INVALID_OPERATION);
670e5c31af7Sopenharmony_ci
671e5c31af7Sopenharmony_ci			startTest("BeginQuery[Indexed] must generate INVALID_OPERATION if <target> is "
672e5c31af7Sopenharmony_ci					  "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and the specified query is "
673e5c31af7Sopenharmony_ci					  "already active on another TRANSFORM_FEEDBACK_STREAM_OVERFLOW "
674e5c31af7Sopenharmony_ci					  "target with a different index.");
675e5c31af7Sopenharmony_ci
676e5c31af7Sopenharmony_ci			for (GLuint i = 0; i < getMaxVertexStreams(); ++i)
677e5c31af7Sopenharmony_ci			{
678e5c31af7Sopenharmony_ci				if (i != m_active_query_stream_index)
679e5c31af7Sopenharmony_ci				{
680e5c31af7Sopenharmony_ci					gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i, m_active_stream_overflow_query);
681e5c31af7Sopenharmony_ci					verifyError(GL_INVALID_OPERATION);
682e5c31af7Sopenharmony_ci
683e5c31af7Sopenharmony_ci					if (i == 0)
684e5c31af7Sopenharmony_ci					{
685e5c31af7Sopenharmony_ci						gl.beginQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_stream_overflow_query);
686e5c31af7Sopenharmony_ci						verifyError(GL_INVALID_OPERATION);
687e5c31af7Sopenharmony_ci					}
688e5c31af7Sopenharmony_ci				}
689e5c31af7Sopenharmony_ci			}
690e5c31af7Sopenharmony_ci		}
691e5c31af7Sopenharmony_ci
692e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
693e5c31af7Sopenharmony_ci
694e5c31af7Sopenharmony_ci		return STOP;
695e5c31af7Sopenharmony_ci	}
696e5c31af7Sopenharmony_ci
697e5c31af7Sopenharmony_ciprotected:
698e5c31af7Sopenharmony_ci	GLuint m_query;
699e5c31af7Sopenharmony_ci	GLuint m_active_overflow_query;
700e5c31af7Sopenharmony_ci	GLuint m_active_stream_overflow_query;
701e5c31af7Sopenharmony_ci	GLuint m_active_query_stream_index;
702e5c31af7Sopenharmony_ci};
703e5c31af7Sopenharmony_ci
704e5c31af7Sopenharmony_ci/*
705e5c31af7Sopenharmony_ci API Incompatible Target Error Test
706e5c31af7Sopenharmony_ci
707e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling
708e5c31af7Sopenharmony_ci BeginQueryIndexed with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW
709e5c31af7Sopenharmony_ci generates an INVALID_OPERATION error if the specified query was
710e5c31af7Sopenharmony_ci previously used as a TRANSFORM_FEEDBACK_OVERFLOW query. Also check
711e5c31af7Sopenharmony_ci the other way around.
712e5c31af7Sopenharmony_ci */
713e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryErrorIncompatibleTarget : public TransformFeedbackOverflowQueryErrorBase
714e5c31af7Sopenharmony_ci{
715e5c31af7Sopenharmony_cipublic:
716e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryErrorIncompatibleTarget(deqp::Context&						   context,
717e5c31af7Sopenharmony_ci														  TransformFeedbackOverflowQueryTests::API api,
718e5c31af7Sopenharmony_ci														  const char*							   name)
719e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQueryErrorBase(context, api, name,
720e5c31af7Sopenharmony_ci												  "Verifies whether an INVALID_OPERATION error is properly generated "
721e5c31af7Sopenharmony_ci												  "if BeginQuery[Indexed] is called with one of "
722e5c31af7Sopenharmony_ci												  "the newly introduced query targets but one that is different than "
723e5c31af7Sopenharmony_ci												  "that used earlier on the same query object.")
724e5c31af7Sopenharmony_ci		, m_overflow_query(0)
725e5c31af7Sopenharmony_ci		, m_stream_overflow_query(0)
726e5c31af7Sopenharmony_ci		, m_incompatible_query(0)
727e5c31af7Sopenharmony_ci	{
728e5c31af7Sopenharmony_ci	}
729e5c31af7Sopenharmony_ci
730e5c31af7Sopenharmony_ci	/* Test case init. */
731e5c31af7Sopenharmony_ci	virtual void init()
732e5c31af7Sopenharmony_ci	{
733e5c31af7Sopenharmony_ci		TransformFeedbackOverflowQueryErrorBase::init();
734e5c31af7Sopenharmony_ci
735e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
736e5c31af7Sopenharmony_ci
737e5c31af7Sopenharmony_ci		gl.genQueries(1, &m_incompatible_query);
738e5c31af7Sopenharmony_ci		gl.beginQuery(GL_SAMPLES_PASSED, m_incompatible_query);
739e5c31af7Sopenharmony_ci		gl.endQuery(GL_SAMPLES_PASSED);
740e5c31af7Sopenharmony_ci
741e5c31af7Sopenharmony_ci		gl.genQueries(1, &m_overflow_query);
742e5c31af7Sopenharmony_ci		gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_overflow_query);
743e5c31af7Sopenharmony_ci		gl.endQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW);
744e5c31af7Sopenharmony_ci
745e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
746e5c31af7Sopenharmony_ci		{
747e5c31af7Sopenharmony_ci			gl.genQueries(1, &m_stream_overflow_query);
748e5c31af7Sopenharmony_ci			gl.beginQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_stream_overflow_query);
749e5c31af7Sopenharmony_ci			gl.endQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW);
750e5c31af7Sopenharmony_ci		}
751e5c31af7Sopenharmony_ci	}
752e5c31af7Sopenharmony_ci
753e5c31af7Sopenharmony_ci	/* Test case deinit */
754e5c31af7Sopenharmony_ci	virtual void deinit()
755e5c31af7Sopenharmony_ci	{
756e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
757e5c31af7Sopenharmony_ci
758e5c31af7Sopenharmony_ci		gl.deleteQueries(1, &m_incompatible_query);
759e5c31af7Sopenharmony_ci
760e5c31af7Sopenharmony_ci		gl.deleteQueries(1, &m_overflow_query);
761e5c31af7Sopenharmony_ci
762e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
763e5c31af7Sopenharmony_ci		{
764e5c31af7Sopenharmony_ci			gl.deleteQueries(1, &m_stream_overflow_query);
765e5c31af7Sopenharmony_ci		}
766e5c31af7Sopenharmony_ci
767e5c31af7Sopenharmony_ci		TransformFeedbackOverflowQueryErrorBase::deinit();
768e5c31af7Sopenharmony_ci	}
769e5c31af7Sopenharmony_ci
770e5c31af7Sopenharmony_ci	/* Test case iterate function. Contains the actual test case logic. */
771e5c31af7Sopenharmony_ci	IterateResult iterate()
772e5c31af7Sopenharmony_ci	{
773e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
774e5c31af7Sopenharmony_ci
775e5c31af7Sopenharmony_ci		startTest("BeginQuery[Indexed] must generate INVALID_OPERATION if <target> is "
776e5c31af7Sopenharmony_ci				  "TRANSFORM_FEEDBACK_OVERFLOW and the specified query was "
777e5c31af7Sopenharmony_ci				  "previously used with another target.");
778e5c31af7Sopenharmony_ci
779e5c31af7Sopenharmony_ci		gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_incompatible_query);
780e5c31af7Sopenharmony_ci		verifyError(GL_INVALID_OPERATION);
781e5c31af7Sopenharmony_ci		gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, m_incompatible_query);
782e5c31af7Sopenharmony_ci		verifyError(GL_INVALID_OPERATION);
783e5c31af7Sopenharmony_ci
784e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
785e5c31af7Sopenharmony_ci		{
786e5c31af7Sopenharmony_ci			gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_stream_overflow_query);
787e5c31af7Sopenharmony_ci			verifyError(GL_INVALID_OPERATION);
788e5c31af7Sopenharmony_ci			gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, m_stream_overflow_query);
789e5c31af7Sopenharmony_ci			verifyError(GL_INVALID_OPERATION);
790e5c31af7Sopenharmony_ci
791e5c31af7Sopenharmony_ci			startTest("BeginQuery[Indexed] must generate INVALID_OPERATION if <target> is "
792e5c31af7Sopenharmony_ci					  "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and the specified query "
793e5c31af7Sopenharmony_ci					  "was previously used with another target.");
794e5c31af7Sopenharmony_ci
795e5c31af7Sopenharmony_ci			gl.beginQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_incompatible_query);
796e5c31af7Sopenharmony_ci			verifyError(GL_INVALID_OPERATION);
797e5c31af7Sopenharmony_ci			gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, 2, m_incompatible_query);
798e5c31af7Sopenharmony_ci			verifyError(GL_INVALID_OPERATION);
799e5c31af7Sopenharmony_ci
800e5c31af7Sopenharmony_ci			gl.beginQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_overflow_query);
801e5c31af7Sopenharmony_ci			verifyError(GL_INVALID_OPERATION);
802e5c31af7Sopenharmony_ci			gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, 2, m_overflow_query);
803e5c31af7Sopenharmony_ci			verifyError(GL_INVALID_OPERATION);
804e5c31af7Sopenharmony_ci		}
805e5c31af7Sopenharmony_ci
806e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
807e5c31af7Sopenharmony_ci
808e5c31af7Sopenharmony_ci		return STOP;
809e5c31af7Sopenharmony_ci	}
810e5c31af7Sopenharmony_ci
811e5c31af7Sopenharmony_ciprotected:
812e5c31af7Sopenharmony_ci	GLuint m_overflow_query;
813e5c31af7Sopenharmony_ci	GLuint m_stream_overflow_query;
814e5c31af7Sopenharmony_ci	GLuint m_incompatible_query;
815e5c31af7Sopenharmony_ci};
816e5c31af7Sopenharmony_ci
817e5c31af7Sopenharmony_ci/*
818e5c31af7Sopenharmony_ci API No Query Active Error Test
819e5c31af7Sopenharmony_ci
820e5c31af7Sopenharmony_ci * Check that calling EndQuery with target TRANSFORM_FEEDBACK_OVERFLOW
821e5c31af7Sopenharmony_ci generates an INVALID_OPERATION error if no query is active for
822e5c31af7Sopenharmony_ci TRANSFORM_FEEDBACK_OVERFLOW.
823e5c31af7Sopenharmony_ci
824e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling
825e5c31af7Sopenharmony_ci EndQueryIndexed with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW
826e5c31af7Sopenharmony_ci generates an INVALID_OPERATION error if no query is active for
827e5c31af7Sopenharmony_ci TRANSFORM_FEEDBACK_STREAM_OVERFLOW for the specified index, even
828e5c31af7Sopenharmony_ci if there is an active query for another index.
829e5c31af7Sopenharmony_ci */
830e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryErrorNoActiveQuery : public TransformFeedbackOverflowQueryErrorBase
831e5c31af7Sopenharmony_ci{
832e5c31af7Sopenharmony_cipublic:
833e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryErrorNoActiveQuery(deqp::Context&							  context,
834e5c31af7Sopenharmony_ci													 TransformFeedbackOverflowQueryTests::API api, const char* name)
835e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQueryErrorBase(context, api, name,
836e5c31af7Sopenharmony_ci												  "Verifies whether an INVALID_OPERATION error is properly generated "
837e5c31af7Sopenharmony_ci												  "if EndQuery[Indexed] is called with a target "
838e5c31af7Sopenharmony_ci												  "(and index) for which there isn't a currently active query.")
839e5c31af7Sopenharmony_ci		, m_active_stream_overflow_query(0)
840e5c31af7Sopenharmony_ci		, m_active_query_stream_index(0)
841e5c31af7Sopenharmony_ci	{
842e5c31af7Sopenharmony_ci	}
843e5c31af7Sopenharmony_ci
844e5c31af7Sopenharmony_ci	/* Test case init. */
845e5c31af7Sopenharmony_ci	virtual void init()
846e5c31af7Sopenharmony_ci	{
847e5c31af7Sopenharmony_ci		TransformFeedbackOverflowQueryErrorBase::init();
848e5c31af7Sopenharmony_ci
849e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
850e5c31af7Sopenharmony_ci
851e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
852e5c31af7Sopenharmony_ci		{
853e5c31af7Sopenharmony_ci			gl.genQueries(1, &m_active_stream_overflow_query);
854e5c31af7Sopenharmony_ci			m_active_query_stream_index = 2;
855e5c31af7Sopenharmony_ci			gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_query_stream_index,
856e5c31af7Sopenharmony_ci								 m_active_stream_overflow_query);
857e5c31af7Sopenharmony_ci		}
858e5c31af7Sopenharmony_ci	}
859e5c31af7Sopenharmony_ci
860e5c31af7Sopenharmony_ci	/* Test case deinit */
861e5c31af7Sopenharmony_ci	virtual void deinit()
862e5c31af7Sopenharmony_ci	{
863e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
864e5c31af7Sopenharmony_ci
865e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
866e5c31af7Sopenharmony_ci		{
867e5c31af7Sopenharmony_ci			gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_query_stream_index);
868e5c31af7Sopenharmony_ci			gl.deleteQueries(1, &m_active_stream_overflow_query);
869e5c31af7Sopenharmony_ci		}
870e5c31af7Sopenharmony_ci
871e5c31af7Sopenharmony_ci		TransformFeedbackOverflowQueryErrorBase::deinit();
872e5c31af7Sopenharmony_ci	}
873e5c31af7Sopenharmony_ci
874e5c31af7Sopenharmony_ci	/* Test case iterate function. Contains the actual test case logic. */
875e5c31af7Sopenharmony_ci	IterateResult iterate()
876e5c31af7Sopenharmony_ci	{
877e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
878e5c31af7Sopenharmony_ci
879e5c31af7Sopenharmony_ci		startTest("EndQuery[Indexed] must generate INVALID_OPERATION if <target> is "
880e5c31af7Sopenharmony_ci				  "TRANSFORM_FEEDBACK_OVERFLOW and there is no query active "
881e5c31af7Sopenharmony_ci				  "for TRANSFORM_FEEDBACK_OVERFLOW.");
882e5c31af7Sopenharmony_ci
883e5c31af7Sopenharmony_ci		gl.endQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW);
884e5c31af7Sopenharmony_ci		verifyError(GL_INVALID_OPERATION);
885e5c31af7Sopenharmony_ci		gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0);
886e5c31af7Sopenharmony_ci		verifyError(GL_INVALID_OPERATION);
887e5c31af7Sopenharmony_ci
888e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
889e5c31af7Sopenharmony_ci		{
890e5c31af7Sopenharmony_ci			startTest("EndQuery[Indexed] must generate INVALID_OPERATION if <target> is "
891e5c31af7Sopenharmony_ci					  "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and there is no query active "
892e5c31af7Sopenharmony_ci					  "for TRANSFORM_FEEDBACK_STREAM_OVERFLOW for the given index.");
893e5c31af7Sopenharmony_ci
894e5c31af7Sopenharmony_ci			for (GLuint i = 0; i < getMaxVertexStreams(); ++i)
895e5c31af7Sopenharmony_ci			{
896e5c31af7Sopenharmony_ci				if (i != m_active_query_stream_index)
897e5c31af7Sopenharmony_ci				{
898e5c31af7Sopenharmony_ci					gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i);
899e5c31af7Sopenharmony_ci					verifyError(GL_INVALID_OPERATION);
900e5c31af7Sopenharmony_ci
901e5c31af7Sopenharmony_ci					if (i == 0)
902e5c31af7Sopenharmony_ci					{
903e5c31af7Sopenharmony_ci						gl.endQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW);
904e5c31af7Sopenharmony_ci						verifyError(GL_INVALID_OPERATION);
905e5c31af7Sopenharmony_ci					}
906e5c31af7Sopenharmony_ci				}
907e5c31af7Sopenharmony_ci			}
908e5c31af7Sopenharmony_ci		}
909e5c31af7Sopenharmony_ci
910e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
911e5c31af7Sopenharmony_ci
912e5c31af7Sopenharmony_ci		return STOP;
913e5c31af7Sopenharmony_ci	}
914e5c31af7Sopenharmony_ci
915e5c31af7Sopenharmony_ciprotected:
916e5c31af7Sopenharmony_ci	GLuint m_active_stream_overflow_query;
917e5c31af7Sopenharmony_ci	GLuint m_active_query_stream_index;
918e5c31af7Sopenharmony_ci};
919e5c31af7Sopenharmony_ci
920e5c31af7Sopenharmony_ci/*
921e5c31af7Sopenharmony_ci Base class of all functionality tests. Helps enforce the following requirements:
922e5c31af7Sopenharmony_ci
923e5c31af7Sopenharmony_ci * Ensuring that QUERY_COUNTER_BITS is at least one for the TRANSFORM_FEEDBACK_OVERFLOW query
924e5c31af7Sopenharmony_ci target before running any test that uses such a query's result.
925e5c31af7Sopenharmony_ci
926e5c31af7Sopenharmony_ci * Ensuring that GL 4.0 or ARB_transform_feedback3 is supported and QUERY_COUNTER_BITS is at least
927e5c31af7Sopenharmony_ci one for the TRANSFORM_FEEDBACK_STREAM_OVERFLOW query target before running any test that
928e5c31af7Sopenharmony_ci uses such a query's result.
929e5c31af7Sopenharmony_ci */
930e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryFunctionalBase : public TransformFeedbackOverflowQueryBaseTest
931e5c31af7Sopenharmony_ci{
932e5c31af7Sopenharmony_ciprotected:
933e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryFunctionalBase(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api,
934e5c31af7Sopenharmony_ci												 const char* name, const char* description)
935e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQueryBaseTest(context, api, name, description)
936e5c31af7Sopenharmony_ci		, m_overflow_query(0)
937e5c31af7Sopenharmony_ci		, m_stream_overflow_query(NULL)
938e5c31af7Sopenharmony_ci		, m_query_buffer(0)
939e5c31af7Sopenharmony_ci		, m_tf_buffer_count(0)
940e5c31af7Sopenharmony_ci		, m_tf_buffer(NULL)
941e5c31af7Sopenharmony_ci		, m_vao(0)
942e5c31af7Sopenharmony_ci		, m_program(0)
943e5c31af7Sopenharmony_ci		, m_checker_program(NULL)
944e5c31af7Sopenharmony_ci	{
945e5c31af7Sopenharmony_ci	}
946e5c31af7Sopenharmony_ci
947e5c31af7Sopenharmony_ci	/* Tells whether functional tests using TRANSFORM_FEEDBACK_OVERFLOW are runnable */
948e5c31af7Sopenharmony_ci	bool canTestOverflow()
949e5c31af7Sopenharmony_ci	{
950e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
951e5c31af7Sopenharmony_ci		GLint				  counterBits;
952e5c31af7Sopenharmony_ci
953e5c31af7Sopenharmony_ci		gl.getQueryiv(GL_TRANSFORM_FEEDBACK_OVERFLOW, GL_QUERY_COUNTER_BITS, &counterBits);
954e5c31af7Sopenharmony_ci
955e5c31af7Sopenharmony_ci		return counterBits > 0;
956e5c31af7Sopenharmony_ci	}
957e5c31af7Sopenharmony_ci
958e5c31af7Sopenharmony_ci	/* Tells whether functional tests using TRANSFORM_FEEDBACK_STREAM_OVERFLOW are runnable */
959e5c31af7Sopenharmony_ci	bool canTestStreamOverflow()
960e5c31af7Sopenharmony_ci	{
961e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
962e5c31af7Sopenharmony_ci		{
963e5c31af7Sopenharmony_ci			const glw::Functions& gl = m_context.getRenderContext().getFunctions();
964e5c31af7Sopenharmony_ci			GLint				  counterBits;
965e5c31af7Sopenharmony_ci
966e5c31af7Sopenharmony_ci			gl.getQueryiv(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, GL_QUERY_COUNTER_BITS, &counterBits);
967e5c31af7Sopenharmony_ci
968e5c31af7Sopenharmony_ci			return counterBits > 0;
969e5c31af7Sopenharmony_ci		}
970e5c31af7Sopenharmony_ci		else
971e5c31af7Sopenharmony_ci		{
972e5c31af7Sopenharmony_ci			return false;
973e5c31af7Sopenharmony_ci		}
974e5c31af7Sopenharmony_ci	}
975e5c31af7Sopenharmony_ci
976e5c31af7Sopenharmony_ci	/* Minimal vertex shader. */
977e5c31af7Sopenharmony_ci	const char* minimalVsh()
978e5c31af7Sopenharmony_ci	{
979e5c31af7Sopenharmony_ci		return "#version 150 core\n"
980e5c31af7Sopenharmony_ci			   "void main() {\n"
981e5c31af7Sopenharmony_ci			   "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
982e5c31af7Sopenharmony_ci			   "}\n";
983e5c31af7Sopenharmony_ci	}
984e5c31af7Sopenharmony_ci
985e5c31af7Sopenharmony_ci	/* Minimal fragment shader */
986e5c31af7Sopenharmony_ci	const char* minimalFsh()
987e5c31af7Sopenharmony_ci	{
988e5c31af7Sopenharmony_ci		return "#version 150 core\n"
989e5c31af7Sopenharmony_ci			   "void main() {}\n";
990e5c31af7Sopenharmony_ci	}
991e5c31af7Sopenharmony_ci
992e5c31af7Sopenharmony_ci	/* Functional test init. Creates necessary query objects. */
993e5c31af7Sopenharmony_ci	virtual void init()
994e5c31af7Sopenharmony_ci	{
995e5c31af7Sopenharmony_ci		TransformFeedbackOverflowQueryBaseTest::init();
996e5c31af7Sopenharmony_ci
997e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
998e5c31af7Sopenharmony_ci
999e5c31af7Sopenharmony_ci		if (canTestOverflow())
1000e5c31af7Sopenharmony_ci		{
1001e5c31af7Sopenharmony_ci			// Setup vertex array
1002e5c31af7Sopenharmony_ci			gl.genVertexArrays(1, &m_vao);
1003e5c31af7Sopenharmony_ci			gl.bindVertexArray(m_vao);
1004e5c31af7Sopenharmony_ci
1005e5c31af7Sopenharmony_ci			// Setup queries
1006e5c31af7Sopenharmony_ci			gl.genQueries(1, &m_overflow_query);
1007e5c31af7Sopenharmony_ci
1008e5c31af7Sopenharmony_ci			if (canTestStreamOverflow())
1009e5c31af7Sopenharmony_ci			{
1010e5c31af7Sopenharmony_ci				m_stream_overflow_query = new GLuint[getMaxVertexStreams()];
1011e5c31af7Sopenharmony_ci
1012e5c31af7Sopenharmony_ci				gl.genQueries(getMaxVertexStreams(), m_stream_overflow_query);
1013e5c31af7Sopenharmony_ci			}
1014e5c31af7Sopenharmony_ci
1015e5c31af7Sopenharmony_ci			// Setup checker program
1016e5c31af7Sopenharmony_ci			m_checker_program =
1017e5c31af7Sopenharmony_ci				new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(minimalVsh(), minimalFsh()));
1018e5c31af7Sopenharmony_ci			if (!m_checker_program->isOk())
1019e5c31af7Sopenharmony_ci			{
1020e5c31af7Sopenharmony_ci				TCU_FAIL("Checker program compilation failed");
1021e5c31af7Sopenharmony_ci			}
1022e5c31af7Sopenharmony_ci
1023e5c31af7Sopenharmony_ci			// Setup transform feedback shader and buffers
1024e5c31af7Sopenharmony_ci			buildTransformFeedbackProgram();
1025e5c31af7Sopenharmony_ci			setupTransformFeedbackBuffers();
1026e5c31af7Sopenharmony_ci		}
1027e5c31af7Sopenharmony_ci		else
1028e5c31af7Sopenharmony_ci		{
1029e5c31af7Sopenharmony_ci			throw tcu::NotSupportedError(
1030e5c31af7Sopenharmony_ci				"QUERY_COUNTER_BITS for TRANSFORM_FEEDBACK_OVERFLOW queries is zero, skipping test");
1031e5c31af7Sopenharmony_ci		}
1032e5c31af7Sopenharmony_ci	}
1033e5c31af7Sopenharmony_ci
1034e5c31af7Sopenharmony_ci	/* Functional test deinit. Deletes created query objects */
1035e5c31af7Sopenharmony_ci	virtual void deinit()
1036e5c31af7Sopenharmony_ci	{
1037e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1038e5c31af7Sopenharmony_ci
1039e5c31af7Sopenharmony_ci		gl.deleteVertexArrays(1, &m_vao);
1040e5c31af7Sopenharmony_ci
1041e5c31af7Sopenharmony_ci		gl.deleteQueries(1, &m_overflow_query);
1042e5c31af7Sopenharmony_ci
1043e5c31af7Sopenharmony_ci		if (canTestStreamOverflow())
1044e5c31af7Sopenharmony_ci		{
1045e5c31af7Sopenharmony_ci			if (m_stream_overflow_query != NULL)
1046e5c31af7Sopenharmony_ci			{
1047e5c31af7Sopenharmony_ci				gl.deleteQueries(getMaxVertexStreams(), m_stream_overflow_query);
1048e5c31af7Sopenharmony_ci
1049e5c31af7Sopenharmony_ci				delete[] m_stream_overflow_query;
1050e5c31af7Sopenharmony_ci			}
1051e5c31af7Sopenharmony_ci		}
1052e5c31af7Sopenharmony_ci
1053e5c31af7Sopenharmony_ci		if (m_checker_program != NULL)
1054e5c31af7Sopenharmony_ci		{
1055e5c31af7Sopenharmony_ci			delete m_checker_program;
1056e5c31af7Sopenharmony_ci		}
1057e5c31af7Sopenharmony_ci
1058e5c31af7Sopenharmony_ci		gl.useProgram(0);
1059e5c31af7Sopenharmony_ci		gl.deleteProgram(m_program);
1060e5c31af7Sopenharmony_ci
1061e5c31af7Sopenharmony_ci		if (m_tf_buffer != NULL)
1062e5c31af7Sopenharmony_ci		{
1063e5c31af7Sopenharmony_ci			gl.deleteBuffers(m_tf_buffer_count, m_tf_buffer);
1064e5c31af7Sopenharmony_ci
1065e5c31af7Sopenharmony_ci			delete[] m_tf_buffer;
1066e5c31af7Sopenharmony_ci		}
1067e5c31af7Sopenharmony_ci
1068e5c31af7Sopenharmony_ci		TransformFeedbackOverflowQueryBaseTest::deinit();
1069e5c31af7Sopenharmony_ci	}
1070e5c31af7Sopenharmony_ci
1071e5c31af7Sopenharmony_ci	/*
1072e5c31af7Sopenharmony_ci	 Basic Checking Mechanism
1073e5c31af7Sopenharmony_ci
1074e5c31af7Sopenharmony_ci	 * Call BeginConditionalRender with mode QUERY_WAIT and with the given
1075e5c31af7Sopenharmony_ci	 query object as parameters. Draw something, then call EndConditional-
1076e5c31af7Sopenharmony_ci	 Render. If the expected result for the query is FALSE, expect
1077e5c31af7Sopenharmony_ci	 conditional render to discard the previous draw command.
1078e5c31af7Sopenharmony_ci
1079e5c31af7Sopenharmony_ci	 * If GL 4.5 or ARB_conditional_render_inverted is supported, call Begin-
1080e5c31af7Sopenharmony_ci	 ConditionalRender with mode QUERY_WAIT_INVERTED and with the given query
1081e5c31af7Sopenharmony_ci	 object as parameters. Draw something, then call EndConditionalRender. If
1082e5c31af7Sopenharmony_ci	 the expected result for the query is TRUE, expect conditional render to
1083e5c31af7Sopenharmony_ci	 discard the previous draw command.
1084e5c31af7Sopenharmony_ci
1085e5c31af7Sopenharmony_ci	 * Finally, check using GetQueryObjectiv with QUERY_RESULT that the result
1086e5c31af7Sopenharmony_ci	 of the query matches the expected result.
1087e5c31af7Sopenharmony_ci
1088e5c31af7Sopenharmony_ci	 * If GL 4.4 or ARB_query_buffer_object is supported then check the result
1089e5c31af7Sopenharmony_ci	 of the query against the expected result also by having a query buffer
1090e5c31af7Sopenharmony_ci	 bound at the time of calling GetQueryObjectiv.
1091e5c31af7Sopenharmony_ci	 */
1092e5c31af7Sopenharmony_ci	bool verifyQueryResult(GLuint query, GLboolean expected)
1093e5c31af7Sopenharmony_ci	{
1094e5c31af7Sopenharmony_ci		const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
1095e5c31af7Sopenharmony_ci		bool				  result = true;
1096e5c31af7Sopenharmony_ci		GLuint				  actual;
1097e5c31af7Sopenharmony_ci
1098e5c31af7Sopenharmony_ci		GLuint current_program = m_context.getContextInfo().getInt(GL_CURRENT_PROGRAM);
1099e5c31af7Sopenharmony_ci		GLuint checker_query, check_result;
1100e5c31af7Sopenharmony_ci
1101e5c31af7Sopenharmony_ci		// We'll use a PRIMITIVES_GENERATED query to test whether conditional
1102e5c31af7Sopenharmony_ci		// rendering actually executed the draw command or not. If the draw command
1103e5c31af7Sopenharmony_ci		// was discarded then the PRIMITIVES_GENERATED query should have a result
1104e5c31af7Sopenharmony_ci		// of zero.
1105e5c31af7Sopenharmony_ci		gl.genQueries(1, &checker_query);
1106e5c31af7Sopenharmony_ci
1107e5c31af7Sopenharmony_ci		gl.useProgram(m_checker_program->getProgram());
1108e5c31af7Sopenharmony_ci
1109e5c31af7Sopenharmony_ci		// Verify that conditional render discards the rendering if the expected
1110e5c31af7Sopenharmony_ci		// result is FALSE and renders otherwise.
1111e5c31af7Sopenharmony_ci		gl.beginConditionalRender(query, GL_QUERY_WAIT);
1112e5c31af7Sopenharmony_ci		gl.beginQuery(GL_PRIMITIVES_GENERATED, checker_query);
1113e5c31af7Sopenharmony_ci		gl.drawArrays(GL_POINTS, 0, 1);
1114e5c31af7Sopenharmony_ci		gl.endQuery(GL_PRIMITIVES_GENERATED);
1115e5c31af7Sopenharmony_ci		gl.endConditionalRender();
1116e5c31af7Sopenharmony_ci		gl.getQueryObjectuiv(checker_query, GL_QUERY_RESULT, &check_result);
1117e5c31af7Sopenharmony_ci		if (check_result != (GLuint)expected)
1118e5c31af7Sopenharmony_ci		{
1119e5c31af7Sopenharmony_ci			result = false;
1120e5c31af7Sopenharmony_ci		}
1121e5c31af7Sopenharmony_ci
1122e5c31af7Sopenharmony_ci		// Verify that an inverted conditional render discards the rendering if
1123e5c31af7Sopenharmony_ci		// the expected result is TRUE and renders otherwise.
1124e5c31af7Sopenharmony_ci		if (supportsConditionalRenderInverted())
1125e5c31af7Sopenharmony_ci		{
1126e5c31af7Sopenharmony_ci			gl.beginConditionalRender(query, GL_QUERY_WAIT_INVERTED);
1127e5c31af7Sopenharmony_ci			gl.beginQuery(GL_PRIMITIVES_GENERATED, checker_query);
1128e5c31af7Sopenharmony_ci			gl.drawArrays(GL_POINTS, 0, 1);
1129e5c31af7Sopenharmony_ci			gl.endQuery(GL_PRIMITIVES_GENERATED);
1130e5c31af7Sopenharmony_ci			gl.endConditionalRender();
1131e5c31af7Sopenharmony_ci			gl.getQueryObjectuiv(checker_query, GL_QUERY_RESULT, &check_result);
1132e5c31af7Sopenharmony_ci			if (check_result == (GLuint)expected)
1133e5c31af7Sopenharmony_ci			{
1134e5c31af7Sopenharmony_ci				result = false;
1135e5c31af7Sopenharmony_ci			}
1136e5c31af7Sopenharmony_ci		}
1137e5c31af7Sopenharmony_ci
1138e5c31af7Sopenharmony_ci		gl.useProgram(current_program);
1139e5c31af7Sopenharmony_ci
1140e5c31af7Sopenharmony_ci		// Verify that the result of the query matches the expected result.
1141e5c31af7Sopenharmony_ci		gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &actual);
1142e5c31af7Sopenharmony_ci		if ((GLboolean)actual != expected)
1143e5c31af7Sopenharmony_ci		{
1144e5c31af7Sopenharmony_ci			result = false;
1145e5c31af7Sopenharmony_ci		}
1146e5c31af7Sopenharmony_ci
1147e5c31af7Sopenharmony_ci		// Verify that the result of the query matches the expected result even
1148e5c31af7Sopenharmony_ci		// when using a query buffer.
1149e5c31af7Sopenharmony_ci		if (supportsQueryBufferObject())
1150e5c31af7Sopenharmony_ci		{
1151e5c31af7Sopenharmony_ci			const GLuint initValue = 0xDEADBEEF;
1152e5c31af7Sopenharmony_ci
1153e5c31af7Sopenharmony_ci			gl.genBuffers(1, &m_query_buffer);
1154e5c31af7Sopenharmony_ci			gl.bindBuffer(GL_QUERY_BUFFER, m_query_buffer);
1155e5c31af7Sopenharmony_ci			gl.bufferData(GL_QUERY_BUFFER, sizeof(initValue), &initValue, GL_STREAM_READ);
1156e5c31af7Sopenharmony_ci			gl.getQueryObjectuiv(query, GL_QUERY_RESULT, NULL);
1157e5c31af7Sopenharmony_ci			gl.getBufferSubData(GL_QUERY_BUFFER, 0, sizeof(actual), &actual);
1158e5c31af7Sopenharmony_ci			gl.deleteBuffers(1, &m_query_buffer);
1159e5c31af7Sopenharmony_ci
1160e5c31af7Sopenharmony_ci			if ((GLboolean)actual != expected)
1161e5c31af7Sopenharmony_ci			{
1162e5c31af7Sopenharmony_ci				result = false;
1163e5c31af7Sopenharmony_ci			}
1164e5c31af7Sopenharmony_ci		}
1165e5c31af7Sopenharmony_ci
1166e5c31af7Sopenharmony_ci		gl.deleteQueries(1, &checker_query);
1167e5c31af7Sopenharmony_ci
1168e5c31af7Sopenharmony_ci		return result;
1169e5c31af7Sopenharmony_ci	}
1170e5c31af7Sopenharmony_ci
1171e5c31af7Sopenharmony_ci	/* Verifies the result of all queries. There can only be up to 5 non-FALSE result queries as none of
1172e5c31af7Sopenharmony_ci	 the tests use more than 4 vertex streams so the rest is assumed to always have a FALSE result. */
1173e5c31af7Sopenharmony_ci	void verifyQueryResults(GLboolean any, GLboolean stream0, GLboolean stream1, GLboolean stream2 = GL_FALSE,
1174e5c31af7Sopenharmony_ci							GLboolean stream3 = GL_FALSE)
1175e5c31af7Sopenharmony_ci	{
1176e5c31af7Sopenharmony_ci		bool result = true;
1177e5c31af7Sopenharmony_ci
1178e5c31af7Sopenharmony_ci		// Verify the result of the TRANSFORM_FEEDBACK_OVERFLOW query.
1179e5c31af7Sopenharmony_ci		result &= verifyQueryResult(m_overflow_query, any);
1180e5c31af7Sopenharmony_ci
1181e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
1182e5c31af7Sopenharmony_ci		{
1183e5c31af7Sopenharmony_ci			// Verify the result of the TRANSFORM_FEEDBACK_STREAM_OVERFLOW queries
1184e5c31af7Sopenharmony_ci			// corresponding to the first 4 vertex streams.
1185e5c31af7Sopenharmony_ci			result &= verifyQueryResult(m_stream_overflow_query[0], stream0);
1186e5c31af7Sopenharmony_ci			result &= verifyQueryResult(m_stream_overflow_query[1], stream1);
1187e5c31af7Sopenharmony_ci			result &= verifyQueryResult(m_stream_overflow_query[2], stream2);
1188e5c31af7Sopenharmony_ci			result &= verifyQueryResult(m_stream_overflow_query[3], stream3);
1189e5c31af7Sopenharmony_ci
1190e5c31af7Sopenharmony_ci			// Expect the rest of the TRANSFORM_FEEDBACK_STREAM_OVERFLOW queries
1191e5c31af7Sopenharmony_ci			// to have a FALSE result.
1192e5c31af7Sopenharmony_ci			for (GLuint i = 4; i < getMaxVertexStreams(); ++i)
1193e5c31af7Sopenharmony_ci			{
1194e5c31af7Sopenharmony_ci				result &= verifyQueryResult(m_stream_overflow_query[i], GL_FALSE);
1195e5c31af7Sopenharmony_ci			}
1196e5c31af7Sopenharmony_ci		}
1197e5c31af7Sopenharmony_ci
1198e5c31af7Sopenharmony_ci		if (!result)
1199e5c31af7Sopenharmony_ci		{
1200e5c31af7Sopenharmony_ci			TCU_FAIL("Failed to validate the results of the queries");
1201e5c31af7Sopenharmony_ci		}
1202e5c31af7Sopenharmony_ci	}
1203e5c31af7Sopenharmony_ci
1204e5c31af7Sopenharmony_ci	/* Single stream version of verifyQueryResults */
1205e5c31af7Sopenharmony_ci	void verifyQueryResults(GLboolean result)
1206e5c31af7Sopenharmony_ci	{
1207e5c31af7Sopenharmony_ci		verifyQueryResults(result, result, GL_FALSE, GL_FALSE, GL_FALSE);
1208e5c31af7Sopenharmony_ci	}
1209e5c31af7Sopenharmony_ci
1210e5c31af7Sopenharmony_ci	/* Compiles and links transform feedback program. */
1211e5c31af7Sopenharmony_ci	void buildTransformFeedbackProgram()
1212e5c31af7Sopenharmony_ci	{
1213e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1214e5c31af7Sopenharmony_ci
1215e5c31af7Sopenharmony_ci		GLint status;
1216e5c31af7Sopenharmony_ci
1217e5c31af7Sopenharmony_ci		m_program = gl.createProgram();
1218e5c31af7Sopenharmony_ci
1219e5c31af7Sopenharmony_ci		const char* vsSource = transformFeedbackVertexShader();
1220e5c31af7Sopenharmony_ci
1221e5c31af7Sopenharmony_ci		GLuint vShader = gl.createShader(GL_VERTEX_SHADER);
1222e5c31af7Sopenharmony_ci		gl.shaderSource(vShader, 1, (const char**)&vsSource, NULL);
1223e5c31af7Sopenharmony_ci		gl.compileShader(vShader);
1224e5c31af7Sopenharmony_ci		gl.getShaderiv(vShader, GL_COMPILE_STATUS, &status);
1225e5c31af7Sopenharmony_ci		if (status == GL_FALSE)
1226e5c31af7Sopenharmony_ci		{
1227e5c31af7Sopenharmony_ci			GLint infoLogLength = 0;
1228e5c31af7Sopenharmony_ci			gl.getShaderiv(vShader, GL_INFO_LOG_LENGTH, &infoLogLength);
1229e5c31af7Sopenharmony_ci
1230e5c31af7Sopenharmony_ci			std::vector<char> infoLogBuf(infoLogLength + 1);
1231e5c31af7Sopenharmony_ci			gl.getShaderInfoLog(vShader, (GLsizei)infoLogBuf.size(), NULL, &infoLogBuf[0]);
1232e5c31af7Sopenharmony_ci
1233e5c31af7Sopenharmony_ci			std::string infoLog = &infoLogBuf[0];
1234e5c31af7Sopenharmony_ci			m_testCtx.getLog().writeShader(QP_SHADER_TYPE_VERTEX, vsSource, false, infoLog.c_str());
1235e5c31af7Sopenharmony_ci
1236e5c31af7Sopenharmony_ci			gl.deleteShader(vShader);
1237e5c31af7Sopenharmony_ci
1238e5c31af7Sopenharmony_ci			TCU_FAIL("Failed to compile transform feedback vertex shader");
1239e5c31af7Sopenharmony_ci		}
1240e5c31af7Sopenharmony_ci		gl.attachShader(m_program, vShader);
1241e5c31af7Sopenharmony_ci		gl.deleteShader(vShader);
1242e5c31af7Sopenharmony_ci
1243e5c31af7Sopenharmony_ci		const char* gsSource = transformFeedbackGeometryShader();
1244e5c31af7Sopenharmony_ci
1245e5c31af7Sopenharmony_ci		if (gsSource)
1246e5c31af7Sopenharmony_ci		{
1247e5c31af7Sopenharmony_ci			GLuint gShader = gl.createShader(GL_GEOMETRY_SHADER);
1248e5c31af7Sopenharmony_ci			gl.shaderSource(gShader, 1, (const char**)&gsSource, NULL);
1249e5c31af7Sopenharmony_ci			gl.compileShader(gShader);
1250e5c31af7Sopenharmony_ci			gl.getShaderiv(gShader, GL_COMPILE_STATUS, &status);
1251e5c31af7Sopenharmony_ci			if (status == GL_FALSE)
1252e5c31af7Sopenharmony_ci			{
1253e5c31af7Sopenharmony_ci				GLint infoLogLength = 0;
1254e5c31af7Sopenharmony_ci				gl.getShaderiv(gShader, GL_INFO_LOG_LENGTH, &infoLogLength);
1255e5c31af7Sopenharmony_ci
1256e5c31af7Sopenharmony_ci				std::vector<char> infoLogBuf(infoLogLength + 1);
1257e5c31af7Sopenharmony_ci				gl.getShaderInfoLog(gShader, (GLsizei)infoLogBuf.size(), NULL, &infoLogBuf[0]);
1258e5c31af7Sopenharmony_ci
1259e5c31af7Sopenharmony_ci				std::string infoLog = &infoLogBuf[0];
1260e5c31af7Sopenharmony_ci				m_testCtx.getLog().writeShader(QP_SHADER_TYPE_GEOMETRY, gsSource, false, infoLog.c_str());
1261e5c31af7Sopenharmony_ci
1262e5c31af7Sopenharmony_ci				gl.deleteShader(gShader);
1263e5c31af7Sopenharmony_ci
1264e5c31af7Sopenharmony_ci				TCU_FAIL("Failed to compile transform feedback geometry shader");
1265e5c31af7Sopenharmony_ci			}
1266e5c31af7Sopenharmony_ci			gl.attachShader(m_program, gShader);
1267e5c31af7Sopenharmony_ci			gl.deleteShader(gShader);
1268e5c31af7Sopenharmony_ci		}
1269e5c31af7Sopenharmony_ci
1270e5c31af7Sopenharmony_ci		gl.transformFeedbackVaryings(m_program, varyingsCount(), varyings(), bufferMode());
1271e5c31af7Sopenharmony_ci		gl.linkProgram(m_program);
1272e5c31af7Sopenharmony_ci		gl.getProgramiv(m_program, GL_LINK_STATUS, &status);
1273e5c31af7Sopenharmony_ci		if (status == GL_FALSE)
1274e5c31af7Sopenharmony_ci		{
1275e5c31af7Sopenharmony_ci			GLint infoLogLength = 0;
1276e5c31af7Sopenharmony_ci			gl.getProgramiv(m_program, GL_INFO_LOG_LENGTH, &infoLogLength);
1277e5c31af7Sopenharmony_ci
1278e5c31af7Sopenharmony_ci			std::vector<char> infoLogBuf(infoLogLength + 1);
1279e5c31af7Sopenharmony_ci			gl.getProgramInfoLog(m_program, (GLsizei)infoLogBuf.size(), NULL, &infoLogBuf[0]);
1280e5c31af7Sopenharmony_ci
1281e5c31af7Sopenharmony_ci			std::string infoLog = &infoLogBuf[0];
1282e5c31af7Sopenharmony_ci			m_testCtx.getLog().writeShader(QP_SHADER_TYPE_VERTEX, vsSource, true, infoLog.c_str());
1283e5c31af7Sopenharmony_ci
1284e5c31af7Sopenharmony_ci			TCU_FAIL("Failed to link transform feedback program");
1285e5c31af7Sopenharmony_ci		}
1286e5c31af7Sopenharmony_ci
1287e5c31af7Sopenharmony_ci		gl.useProgram(m_program);
1288e5c31af7Sopenharmony_ci	}
1289e5c31af7Sopenharmony_ci
1290e5c31af7Sopenharmony_ci	/* Generates a number of transform feedback buffers and binds them. */
1291e5c31af7Sopenharmony_ci	void setupTransformFeedbackBuffers()
1292e5c31af7Sopenharmony_ci	{
1293e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1294e5c31af7Sopenharmony_ci
1295e5c31af7Sopenharmony_ci		m_tf_buffer_count = bufferCount();
1296e5c31af7Sopenharmony_ci
1297e5c31af7Sopenharmony_ci		m_tf_buffer = new GLuint[m_tf_buffer_count];
1298e5c31af7Sopenharmony_ci
1299e5c31af7Sopenharmony_ci		gl.genBuffers(m_tf_buffer_count, m_tf_buffer);
1300e5c31af7Sopenharmony_ci
1301e5c31af7Sopenharmony_ci		for (GLint i = 0; i < m_tf_buffer_count; ++i)
1302e5c31af7Sopenharmony_ci		{
1303e5c31af7Sopenharmony_ci			gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_tf_buffer[i]);
1304e5c31af7Sopenharmony_ci			gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bufferSize(i), NULL, GL_DYNAMIC_COPY);
1305e5c31af7Sopenharmony_ci		}
1306e5c31af7Sopenharmony_ci	}
1307e5c31af7Sopenharmony_ci
1308e5c31af7Sopenharmony_ci	/* Starts all overflow queries. */
1309e5c31af7Sopenharmony_ci	void beginQueries()
1310e5c31af7Sopenharmony_ci	{
1311e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1312e5c31af7Sopenharmony_ci
1313e5c31af7Sopenharmony_ci		gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_overflow_query);
1314e5c31af7Sopenharmony_ci
1315e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
1316e5c31af7Sopenharmony_ci		{
1317e5c31af7Sopenharmony_ci			for (GLuint i = 0; i < getMaxVertexStreams(); ++i)
1318e5c31af7Sopenharmony_ci			{
1319e5c31af7Sopenharmony_ci				gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i, m_stream_overflow_query[i]);
1320e5c31af7Sopenharmony_ci			}
1321e5c31af7Sopenharmony_ci		}
1322e5c31af7Sopenharmony_ci	}
1323e5c31af7Sopenharmony_ci
1324e5c31af7Sopenharmony_ci	/* Stops all overflow queries. */
1325e5c31af7Sopenharmony_ci	void endQueries()
1326e5c31af7Sopenharmony_ci	{
1327e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1328e5c31af7Sopenharmony_ci
1329e5c31af7Sopenharmony_ci		gl.endQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW);
1330e5c31af7Sopenharmony_ci
1331e5c31af7Sopenharmony_ci		if (supportsTransformFeedback3())
1332e5c31af7Sopenharmony_ci		{
1333e5c31af7Sopenharmony_ci			for (GLuint i = 0; i < getMaxVertexStreams(); ++i)
1334e5c31af7Sopenharmony_ci			{
1335e5c31af7Sopenharmony_ci				gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i);
1336e5c31af7Sopenharmony_ci			}
1337e5c31af7Sopenharmony_ci		}
1338e5c31af7Sopenharmony_ci	}
1339e5c31af7Sopenharmony_ci
1340e5c31af7Sopenharmony_ci	/* Draws a set of points to vertex stream #0 while having the overflow queries active. */
1341e5c31af7Sopenharmony_ci	void drawPoints(GLsizei count)
1342e5c31af7Sopenharmony_ci	{
1343e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1344e5c31af7Sopenharmony_ci
1345e5c31af7Sopenharmony_ci		beginQueries();
1346e5c31af7Sopenharmony_ci		gl.drawArrays(GL_POINTS, 0, count);
1347e5c31af7Sopenharmony_ci		endQueries();
1348e5c31af7Sopenharmony_ci	}
1349e5c31af7Sopenharmony_ci
1350e5c31af7Sopenharmony_ci	/* Draws a set of triangles to vertex stream #0 while having the overflow queries active. */
1351e5c31af7Sopenharmony_ci	void drawTriangles(GLsizei count)
1352e5c31af7Sopenharmony_ci	{
1353e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1354e5c31af7Sopenharmony_ci
1355e5c31af7Sopenharmony_ci		beginQueries();
1356e5c31af7Sopenharmony_ci		gl.drawArrays(GL_TRIANGLES, 0, count * 3);
1357e5c31af7Sopenharmony_ci		endQueries();
1358e5c31af7Sopenharmony_ci	}
1359e5c31af7Sopenharmony_ci
1360e5c31af7Sopenharmony_ci	/* Vertex shader to use for transform feedback. */
1361e5c31af7Sopenharmony_ci	virtual const char* transformFeedbackVertexShader() = 0;
1362e5c31af7Sopenharmony_ci
1363e5c31af7Sopenharmony_ci	/* Geometry shader to use for transform feedback. */
1364e5c31af7Sopenharmony_ci	virtual const char* transformFeedbackGeometryShader() = 0;
1365e5c31af7Sopenharmony_ci
1366e5c31af7Sopenharmony_ci	/* Returns the number of transform feedback varyings. */
1367e5c31af7Sopenharmony_ci	virtual GLsizei varyingsCount() = 0;
1368e5c31af7Sopenharmony_ci
1369e5c31af7Sopenharmony_ci	/* Returns the array of transform feedback varying names. */
1370e5c31af7Sopenharmony_ci	virtual const char** varyings() = 0;
1371e5c31af7Sopenharmony_ci
1372e5c31af7Sopenharmony_ci	/* Returns the transform feedback buffer mode. */
1373e5c31af7Sopenharmony_ci	virtual GLenum bufferMode() = 0;
1374e5c31af7Sopenharmony_ci
1375e5c31af7Sopenharmony_ci	/* Returns the number of transform feedback buffers. */
1376e5c31af7Sopenharmony_ci	virtual GLsizei bufferCount() = 0;
1377e5c31af7Sopenharmony_ci
1378e5c31af7Sopenharmony_ci	/* Returns the size of the specified transform feedback buffer. */
1379e5c31af7Sopenharmony_ci	virtual GLsizei bufferSize(GLint index) = 0;
1380e5c31af7Sopenharmony_ci
1381e5c31af7Sopenharmony_ciprotected:
1382e5c31af7Sopenharmony_ci	GLuint				m_overflow_query;
1383e5c31af7Sopenharmony_ci	GLuint*				m_stream_overflow_query;
1384e5c31af7Sopenharmony_ci	GLuint				m_query_buffer;
1385e5c31af7Sopenharmony_ci	GLsizei				m_tf_buffer_count;
1386e5c31af7Sopenharmony_ci	GLuint*				m_tf_buffer;
1387e5c31af7Sopenharmony_ci	GLuint				m_vao;
1388e5c31af7Sopenharmony_ci	GLuint				m_program;
1389e5c31af7Sopenharmony_ci	glu::ShaderProgram* m_checker_program;
1390e5c31af7Sopenharmony_ci};
1391e5c31af7Sopenharmony_ci
1392e5c31af7Sopenharmony_ci/*
1393e5c31af7Sopenharmony_ci Base class for all single stream test cases.
1394e5c31af7Sopenharmony_ci */
1395e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQuerySingleStreamBase : public TransformFeedbackOverflowQueryFunctionalBase
1396e5c31af7Sopenharmony_ci{
1397e5c31af7Sopenharmony_ciprotected:
1398e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQuerySingleStreamBase(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api,
1399e5c31af7Sopenharmony_ci												   const char* name, const char* description)
1400e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQueryFunctionalBase(context, api, name, description)
1401e5c31af7Sopenharmony_ci	{
1402e5c31af7Sopenharmony_ci	}
1403e5c31af7Sopenharmony_ci
1404e5c31af7Sopenharmony_ci	/* Vertex shader to use for transform feedback. */
1405e5c31af7Sopenharmony_ci	virtual const char* transformFeedbackVertexShader()
1406e5c31af7Sopenharmony_ci	{
1407e5c31af7Sopenharmony_ci		return "#version 150 core\n"
1408e5c31af7Sopenharmony_ci			   "out float output1;\n"
1409e5c31af7Sopenharmony_ci			   "out float output2;\n"
1410e5c31af7Sopenharmony_ci			   "out float output3;\n"
1411e5c31af7Sopenharmony_ci			   "out float output4;\n"
1412e5c31af7Sopenharmony_ci			   "void main() {\n"
1413e5c31af7Sopenharmony_ci			   "    output1 = 1.0;\n"
1414e5c31af7Sopenharmony_ci			   "    output2 = 2.0;\n"
1415e5c31af7Sopenharmony_ci			   "    output3 = 3.0;\n"
1416e5c31af7Sopenharmony_ci			   "    output4 = 4.0;\n"
1417e5c31af7Sopenharmony_ci			   "}";
1418e5c31af7Sopenharmony_ci	}
1419e5c31af7Sopenharmony_ci
1420e5c31af7Sopenharmony_ci	/* No geometry shader for single stream test cases. */
1421e5c31af7Sopenharmony_ci	virtual const char* transformFeedbackGeometryShader()
1422e5c31af7Sopenharmony_ci	{
1423e5c31af7Sopenharmony_ci		return NULL;
1424e5c31af7Sopenharmony_ci	}
1425e5c31af7Sopenharmony_ci
1426e5c31af7Sopenharmony_ci	/* There are a total of 4 varyings. */
1427e5c31af7Sopenharmony_ci	virtual GLsizei varyingsCount()
1428e5c31af7Sopenharmony_ci	{
1429e5c31af7Sopenharmony_ci		return 4;
1430e5c31af7Sopenharmony_ci	}
1431e5c31af7Sopenharmony_ci
1432e5c31af7Sopenharmony_ci	/* The varying name list contains all outputs in order. */
1433e5c31af7Sopenharmony_ci	virtual const char** varyings()
1434e5c31af7Sopenharmony_ci	{
1435e5c31af7Sopenharmony_ci		static const char* vars[] = { "output1", "output2", "output3", "output4" };
1436e5c31af7Sopenharmony_ci		return vars;
1437e5c31af7Sopenharmony_ci	}
1438e5c31af7Sopenharmony_ci};
1439e5c31af7Sopenharmony_ci
1440e5c31af7Sopenharmony_ci/*
1441e5c31af7Sopenharmony_ci Test case #1 - Basic single stream, interleaved attributes.
1442e5c31af7Sopenharmony_ci */
1443e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryBasicSingleStreamInterleavedAttribs
1444e5c31af7Sopenharmony_ci	: public TransformFeedbackOverflowQuerySingleStreamBase
1445e5c31af7Sopenharmony_ci{
1446e5c31af7Sopenharmony_cipublic:
1447e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryBasicSingleStreamInterleavedAttribs(deqp::Context&						   context,
1448e5c31af7Sopenharmony_ci																	  TransformFeedbackOverflowQueryTests::API api,
1449e5c31af7Sopenharmony_ci																	  const char*							   name)
1450e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQuerySingleStreamBase(context, api, name,
1451e5c31af7Sopenharmony_ci														 "Basic single stream, interleaved attributes.")
1452e5c31af7Sopenharmony_ci	{
1453e5c31af7Sopenharmony_ci	}
1454e5c31af7Sopenharmony_ci
1455e5c31af7Sopenharmony_ci	/* Use interleaved attributes. */
1456e5c31af7Sopenharmony_ci	virtual GLenum bufferMode()
1457e5c31af7Sopenharmony_ci	{
1458e5c31af7Sopenharmony_ci		return GL_INTERLEAVED_ATTRIBS;
1459e5c31af7Sopenharmony_ci	}
1460e5c31af7Sopenharmony_ci
1461e5c31af7Sopenharmony_ci	/* A single transform feedback buffer is enough. */
1462e5c31af7Sopenharmony_ci	virtual GLsizei bufferCount()
1463e5c31af7Sopenharmony_ci	{
1464e5c31af7Sopenharmony_ci		return 1;
1465e5c31af7Sopenharmony_ci	}
1466e5c31af7Sopenharmony_ci
1467e5c31af7Sopenharmony_ci	/* The transform feedback buffer should be able to capture exactly 10 vertices. */
1468e5c31af7Sopenharmony_ci	virtual GLsizei bufferSize(GLint index)
1469e5c31af7Sopenharmony_ci	{
1470e5c31af7Sopenharmony_ci		(void)index;
1471e5c31af7Sopenharmony_ci		return static_cast<GLsizei>(10 * sizeof(GLfloat) * varyingsCount());
1472e5c31af7Sopenharmony_ci	}
1473e5c31af7Sopenharmony_ci
1474e5c31af7Sopenharmony_ci	/* Test case iterate function. Contains the actual test case logic. */
1475e5c31af7Sopenharmony_ci	IterateResult iterate()
1476e5c31af7Sopenharmony_ci	{
1477e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1478e5c31af7Sopenharmony_ci
1479e5c31af7Sopenharmony_ci		// Call BeginTransformFeedback with mode POINTS.
1480e5c31af7Sopenharmony_ci		gl.beginTransformFeedback(GL_POINTS);
1481e5c31af7Sopenharmony_ci
1482e5c31af7Sopenharmony_ci		// Start the query, submit draw that results in feeding back exactly 10
1483e5c31af7Sopenharmony_ci		// points, then stop the query.
1484e5c31af7Sopenharmony_ci		drawPoints(10);
1485e5c31af7Sopenharmony_ci
1486e5c31af7Sopenharmony_ci		// Call EndTransformFeedback.
1487e5c31af7Sopenharmony_ci		gl.endTransformFeedback();
1488e5c31af7Sopenharmony_ci
1489e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
1490e5c31af7Sopenharmony_ci		// query is FALSE.
1491e5c31af7Sopenharmony_ci		verifyQueryResults(GL_FALSE);
1492e5c31af7Sopenharmony_ci
1493e5c31af7Sopenharmony_ci		// Repeat the above steps, but this time feed back more than 10 vertices
1494e5c31af7Sopenharmony_ci		// and expect the result of the query to be TRUE.
1495e5c31af7Sopenharmony_ci		gl.beginTransformFeedback(GL_POINTS);
1496e5c31af7Sopenharmony_ci		drawPoints(11);
1497e5c31af7Sopenharmony_ci		gl.endTransformFeedback();
1498e5c31af7Sopenharmony_ci		verifyQueryResults(GL_TRUE);
1499e5c31af7Sopenharmony_ci
1500e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1501e5c31af7Sopenharmony_ci
1502e5c31af7Sopenharmony_ci		return STOP;
1503e5c31af7Sopenharmony_ci	}
1504e5c31af7Sopenharmony_ci};
1505e5c31af7Sopenharmony_ci
1506e5c31af7Sopenharmony_ci/*
1507e5c31af7Sopenharmony_ci Test case #2 - Basic single stream, separate attributes.
1508e5c31af7Sopenharmony_ci */
1509e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryBasicSingleStreamSeparateAttribs
1510e5c31af7Sopenharmony_ci	: public TransformFeedbackOverflowQuerySingleStreamBase
1511e5c31af7Sopenharmony_ci{
1512e5c31af7Sopenharmony_cipublic:
1513e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryBasicSingleStreamSeparateAttribs(deqp::Context&							context,
1514e5c31af7Sopenharmony_ci																   TransformFeedbackOverflowQueryTests::API api,
1515e5c31af7Sopenharmony_ci																   const char*								name)
1516e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQuerySingleStreamBase(context, api, name,
1517e5c31af7Sopenharmony_ci														 "Basic single stream, separate attributes.")
1518e5c31af7Sopenharmony_ci	{
1519e5c31af7Sopenharmony_ci	}
1520e5c31af7Sopenharmony_ci
1521e5c31af7Sopenharmony_ci	/* Use separate attributes. */
1522e5c31af7Sopenharmony_ci	virtual GLenum bufferMode()
1523e5c31af7Sopenharmony_ci	{
1524e5c31af7Sopenharmony_ci		return GL_SEPARATE_ATTRIBS;
1525e5c31af7Sopenharmony_ci	}
1526e5c31af7Sopenharmony_ci
1527e5c31af7Sopenharmony_ci	/* We need a separate buffer for each varying. */
1528e5c31af7Sopenharmony_ci	virtual GLsizei bufferCount()
1529e5c31af7Sopenharmony_ci	{
1530e5c31af7Sopenharmony_ci		return varyingsCount();
1531e5c31af7Sopenharmony_ci	}
1532e5c31af7Sopenharmony_ci
1533e5c31af7Sopenharmony_ci	/* One of the transform feedback buffers should be able to capture exactly 12 vertices,
1534e5c31af7Sopenharmony_ci	 the others should be able to capture at least 15 vertices. */
1535e5c31af7Sopenharmony_ci	virtual GLsizei bufferSize(GLint index)
1536e5c31af7Sopenharmony_ci	{
1537e5c31af7Sopenharmony_ci		if (index == 1)
1538e5c31af7Sopenharmony_ci		{
1539e5c31af7Sopenharmony_ci			return 12 * sizeof(GLfloat);
1540e5c31af7Sopenharmony_ci		}
1541e5c31af7Sopenharmony_ci		else
1542e5c31af7Sopenharmony_ci		{
1543e5c31af7Sopenharmony_ci			return 15 * sizeof(GLfloat);
1544e5c31af7Sopenharmony_ci		}
1545e5c31af7Sopenharmony_ci	}
1546e5c31af7Sopenharmony_ci
1547e5c31af7Sopenharmony_ci	/* Test case iterate function. Contains the actual test case logic. */
1548e5c31af7Sopenharmony_ci	IterateResult iterate()
1549e5c31af7Sopenharmony_ci	{
1550e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1551e5c31af7Sopenharmony_ci
1552e5c31af7Sopenharmony_ci		// Call BeginTransformFeedback with mode TRIANGLES.
1553e5c31af7Sopenharmony_ci		gl.beginTransformFeedback(GL_TRIANGLES);
1554e5c31af7Sopenharmony_ci
1555e5c31af7Sopenharmony_ci		// Start the query, submit draw that results in feeding back exactly 4
1556e5c31af7Sopenharmony_ci		// triangles, then stop the query.
1557e5c31af7Sopenharmony_ci		drawTriangles(4);
1558e5c31af7Sopenharmony_ci
1559e5c31af7Sopenharmony_ci		// Call EndTransformFeedback.
1560e5c31af7Sopenharmony_ci		gl.endTransformFeedback();
1561e5c31af7Sopenharmony_ci
1562e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
1563e5c31af7Sopenharmony_ci		// query is FALSE.
1564e5c31af7Sopenharmony_ci		verifyQueryResults(GL_FALSE);
1565e5c31af7Sopenharmony_ci
1566e5c31af7Sopenharmony_ci		// Repeat the above steps, but this time feed back exactly 5 triangles
1567e5c31af7Sopenharmony_ci		// and expect the result of the query to be TRUE.
1568e5c31af7Sopenharmony_ci		gl.beginTransformFeedback(GL_TRIANGLES);
1569e5c31af7Sopenharmony_ci		drawTriangles(5);
1570e5c31af7Sopenharmony_ci		gl.endTransformFeedback();
1571e5c31af7Sopenharmony_ci		verifyQueryResults(GL_TRUE);
1572e5c31af7Sopenharmony_ci
1573e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1574e5c31af7Sopenharmony_ci
1575e5c31af7Sopenharmony_ci		return STOP;
1576e5c31af7Sopenharmony_ci	}
1577e5c31af7Sopenharmony_ci};
1578e5c31af7Sopenharmony_ci
1579e5c31af7Sopenharmony_ci/*
1580e5c31af7Sopenharmony_ci Test case #3 - Advanced single stream, interleaved attributes.
1581e5c31af7Sopenharmony_ci */
1582e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryAdvancedSingleStreamInterleavedAttribs
1583e5c31af7Sopenharmony_ci	: public TransformFeedbackOverflowQuerySingleStreamBase
1584e5c31af7Sopenharmony_ci{
1585e5c31af7Sopenharmony_cipublic:
1586e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryAdvancedSingleStreamInterleavedAttribs(deqp::Context& context,
1587e5c31af7Sopenharmony_ci																		 TransformFeedbackOverflowQueryTests::API api,
1588e5c31af7Sopenharmony_ci																		 const char*							  name)
1589e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQuerySingleStreamBase(context, api, name,
1590e5c31af7Sopenharmony_ci														 "Advanced single stream, interleaved attributes.")
1591e5c31af7Sopenharmony_ci	{
1592e5c31af7Sopenharmony_ci	}
1593e5c31af7Sopenharmony_ci
1594e5c31af7Sopenharmony_ci	/* Use interleaved attributes. */
1595e5c31af7Sopenharmony_ci	virtual GLenum bufferMode()
1596e5c31af7Sopenharmony_ci	{
1597e5c31af7Sopenharmony_ci		return GL_INTERLEAVED_ATTRIBS;
1598e5c31af7Sopenharmony_ci	}
1599e5c31af7Sopenharmony_ci
1600e5c31af7Sopenharmony_ci	/* A single transform feedback buffer is enough. */
1601e5c31af7Sopenharmony_ci	virtual GLsizei bufferCount()
1602e5c31af7Sopenharmony_ci	{
1603e5c31af7Sopenharmony_ci		return 1;
1604e5c31af7Sopenharmony_ci	}
1605e5c31af7Sopenharmony_ci
1606e5c31af7Sopenharmony_ci	/* The transform feedback buffer should be able to capture exactly 10 vertices. */
1607e5c31af7Sopenharmony_ci	virtual GLsizei bufferSize(GLint index)
1608e5c31af7Sopenharmony_ci	{
1609e5c31af7Sopenharmony_ci		(void)index;
1610e5c31af7Sopenharmony_ci		return static_cast<GLsizei>(10 * sizeof(GLfloat) * varyingsCount());
1611e5c31af7Sopenharmony_ci	}
1612e5c31af7Sopenharmony_ci
1613e5c31af7Sopenharmony_ci	/* Test case iterate function. Contains the actual test case logic. */
1614e5c31af7Sopenharmony_ci	IterateResult iterate()
1615e5c31af7Sopenharmony_ci	{
1616e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1617e5c31af7Sopenharmony_ci
1618e5c31af7Sopenharmony_ci		// If GL 4.0 and ARB_transform_feedback2 are not supported then skip this
1619e5c31af7Sopenharmony_ci		// test case.
1620e5c31af7Sopenharmony_ci		if (!supportsTransformFeedback2())
1621e5c31af7Sopenharmony_ci		{
1622e5c31af7Sopenharmony_ci			throw tcu::NotSupportedError("Required transform_feedback2 extension is not supported");
1623e5c31af7Sopenharmony_ci		}
1624e5c31af7Sopenharmony_ci
1625e5c31af7Sopenharmony_ci		// Call BeginTransformFeedback with mode POINTS.
1626e5c31af7Sopenharmony_ci		gl.beginTransformFeedback(GL_POINTS);
1627e5c31af7Sopenharmony_ci
1628e5c31af7Sopenharmony_ci		// Start the query, submit draw that results in feeding back exactly 8
1629e5c31af7Sopenharmony_ci		// triangles, then stop the query.
1630e5c31af7Sopenharmony_ci		drawPoints(8);
1631e5c31af7Sopenharmony_ci
1632e5c31af7Sopenharmony_ci		// Call PauseTransformFeedback.
1633e5c31af7Sopenharmony_ci		gl.pauseTransformFeedback();
1634e5c31af7Sopenharmony_ci
1635e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
1636e5c31af7Sopenharmony_ci		// query is FALSE.
1637e5c31af7Sopenharmony_ci		verifyQueryResults(GL_FALSE);
1638e5c31af7Sopenharmony_ci
1639e5c31af7Sopenharmony_ci		// Start the query, submit draw that would result in feeding back more than
1640e5c31af7Sopenharmony_ci		// 10 points if transform feedback wasn't paused, then stop the query.
1641e5c31af7Sopenharmony_ci		drawPoints(11);
1642e5c31af7Sopenharmony_ci
1643e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
1644e5c31af7Sopenharmony_ci		// query is FALSE.
1645e5c31af7Sopenharmony_ci		verifyQueryResults(GL_FALSE);
1646e5c31af7Sopenharmony_ci
1647e5c31af7Sopenharmony_ci		// Call ResumeTransformFeedback.
1648e5c31af7Sopenharmony_ci		gl.resumeTransformFeedback();
1649e5c31af7Sopenharmony_ci
1650e5c31af7Sopenharmony_ci		// Start the query, submit draw that results in feeding back exactly 1
1651e5c31af7Sopenharmony_ci		// point, then stop the query.
1652e5c31af7Sopenharmony_ci		drawPoints(1);
1653e5c31af7Sopenharmony_ci
1654e5c31af7Sopenharmony_ci		// Call PauseTransformFeedback.
1655e5c31af7Sopenharmony_ci		gl.pauseTransformFeedback();
1656e5c31af7Sopenharmony_ci
1657e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
1658e5c31af7Sopenharmony_ci		// query is FALSE.
1659e5c31af7Sopenharmony_ci		verifyQueryResults(GL_FALSE);
1660e5c31af7Sopenharmony_ci
1661e5c31af7Sopenharmony_ci		// Call ResumeTransformFeedback.
1662e5c31af7Sopenharmony_ci		gl.resumeTransformFeedback();
1663e5c31af7Sopenharmony_ci
1664e5c31af7Sopenharmony_ci		// Start the query, submit draw that results in feeding back exactly 2
1665e5c31af7Sopenharmony_ci		// point, then stop the query.
1666e5c31af7Sopenharmony_ci		drawPoints(2);
1667e5c31af7Sopenharmony_ci
1668e5c31af7Sopenharmony_ci		// Call EndTransformFeedback.
1669e5c31af7Sopenharmony_ci		gl.endTransformFeedback();
1670e5c31af7Sopenharmony_ci
1671e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
1672e5c31af7Sopenharmony_ci		// query is TRUE.
1673e5c31af7Sopenharmony_ci		verifyQueryResults(GL_TRUE);
1674e5c31af7Sopenharmony_ci
1675e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1676e5c31af7Sopenharmony_ci
1677e5c31af7Sopenharmony_ci		return STOP;
1678e5c31af7Sopenharmony_ci	}
1679e5c31af7Sopenharmony_ci};
1680e5c31af7Sopenharmony_ci
1681e5c31af7Sopenharmony_ci/*
1682e5c31af7Sopenharmony_ci Test case #4 - Advanced single stream, separate attributes.
1683e5c31af7Sopenharmony_ci */
1684e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryAdvancedSingleStreamSeparateAttribs
1685e5c31af7Sopenharmony_ci	: public TransformFeedbackOverflowQuerySingleStreamBase
1686e5c31af7Sopenharmony_ci{
1687e5c31af7Sopenharmony_cipublic:
1688e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryAdvancedSingleStreamSeparateAttribs(deqp::Context&						   context,
1689e5c31af7Sopenharmony_ci																	  TransformFeedbackOverflowQueryTests::API api,
1690e5c31af7Sopenharmony_ci																	  const char*							   name)
1691e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQuerySingleStreamBase(context, api, name,
1692e5c31af7Sopenharmony_ci														 "Advanced single stream, separate attributes.")
1693e5c31af7Sopenharmony_ci	{
1694e5c31af7Sopenharmony_ci	}
1695e5c31af7Sopenharmony_ci
1696e5c31af7Sopenharmony_ci	/* Use separate attributes. */
1697e5c31af7Sopenharmony_ci	virtual GLenum bufferMode()
1698e5c31af7Sopenharmony_ci	{
1699e5c31af7Sopenharmony_ci		return GL_SEPARATE_ATTRIBS;
1700e5c31af7Sopenharmony_ci	}
1701e5c31af7Sopenharmony_ci
1702e5c31af7Sopenharmony_ci	/* We need a separate buffer for each varying. */
1703e5c31af7Sopenharmony_ci	virtual GLsizei bufferCount()
1704e5c31af7Sopenharmony_ci	{
1705e5c31af7Sopenharmony_ci		return varyingsCount();
1706e5c31af7Sopenharmony_ci	}
1707e5c31af7Sopenharmony_ci
1708e5c31af7Sopenharmony_ci	/* One of the transform feedback buffers should be able to capture exactly 12 vertices,
1709e5c31af7Sopenharmony_ci	 the others should be able to capture at least 15 vertices. */
1710e5c31af7Sopenharmony_ci	virtual GLsizei bufferSize(GLint index)
1711e5c31af7Sopenharmony_ci	{
1712e5c31af7Sopenharmony_ci		if (index == 2)
1713e5c31af7Sopenharmony_ci		{
1714e5c31af7Sopenharmony_ci			return 12 * sizeof(GLfloat);
1715e5c31af7Sopenharmony_ci		}
1716e5c31af7Sopenharmony_ci		else
1717e5c31af7Sopenharmony_ci		{
1718e5c31af7Sopenharmony_ci			return 15 * sizeof(GLfloat);
1719e5c31af7Sopenharmony_ci		}
1720e5c31af7Sopenharmony_ci	}
1721e5c31af7Sopenharmony_ci
1722e5c31af7Sopenharmony_ci	/* Test case iterate function. Contains the actual test case logic. */
1723e5c31af7Sopenharmony_ci	IterateResult iterate()
1724e5c31af7Sopenharmony_ci	{
1725e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1726e5c31af7Sopenharmony_ci
1727e5c31af7Sopenharmony_ci		// If GL 4.0 and ARB_transform_feedback2 are not supported then skip this
1728e5c31af7Sopenharmony_ci		// test case.
1729e5c31af7Sopenharmony_ci		if (!supportsTransformFeedback2())
1730e5c31af7Sopenharmony_ci		{
1731e5c31af7Sopenharmony_ci			throw tcu::NotSupportedError("Required transform_feedback2 extension is not supported");
1732e5c31af7Sopenharmony_ci		}
1733e5c31af7Sopenharmony_ci
1734e5c31af7Sopenharmony_ci		// Call BeginTransformFeedback with mode TRIANGLES.
1735e5c31af7Sopenharmony_ci		gl.beginTransformFeedback(GL_TRIANGLES);
1736e5c31af7Sopenharmony_ci
1737e5c31af7Sopenharmony_ci		// Start the query, submit draw that results in feeding back exactly 2
1738e5c31af7Sopenharmony_ci		// triangles, then stop the query.
1739e5c31af7Sopenharmony_ci		drawTriangles(2);
1740e5c31af7Sopenharmony_ci
1741e5c31af7Sopenharmony_ci		// Call PauseTransformFeedback.
1742e5c31af7Sopenharmony_ci		gl.pauseTransformFeedback();
1743e5c31af7Sopenharmony_ci
1744e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
1745e5c31af7Sopenharmony_ci		// query is FALSE.
1746e5c31af7Sopenharmony_ci		verifyQueryResults(GL_FALSE);
1747e5c31af7Sopenharmony_ci
1748e5c31af7Sopenharmony_ci		// Start the query, submit draw that would result in feeding back more than
1749e5c31af7Sopenharmony_ci		// 4 triangles if transform feedback wasn't paused, then stop the query.
1750e5c31af7Sopenharmony_ci		drawTriangles(4);
1751e5c31af7Sopenharmony_ci
1752e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
1753e5c31af7Sopenharmony_ci		// query is FALSE.
1754e5c31af7Sopenharmony_ci		verifyQueryResults(GL_FALSE);
1755e5c31af7Sopenharmony_ci
1756e5c31af7Sopenharmony_ci		// Call ResumeTransformFeedback.
1757e5c31af7Sopenharmony_ci		gl.resumeTransformFeedback();
1758e5c31af7Sopenharmony_ci
1759e5c31af7Sopenharmony_ci		// Start the query, submit draw that results in feeding back exactly 2
1760e5c31af7Sopenharmony_ci		// triangles, then stop the query.
1761e5c31af7Sopenharmony_ci		drawTriangles(2);
1762e5c31af7Sopenharmony_ci
1763e5c31af7Sopenharmony_ci		// Call PauseTransformFeedback.
1764e5c31af7Sopenharmony_ci		gl.pauseTransformFeedback();
1765e5c31af7Sopenharmony_ci
1766e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
1767e5c31af7Sopenharmony_ci		// query is FALSE.
1768e5c31af7Sopenharmony_ci		verifyQueryResults(GL_FALSE);
1769e5c31af7Sopenharmony_ci
1770e5c31af7Sopenharmony_ci		// Call ResumeTransformFeedback.
1771e5c31af7Sopenharmony_ci		gl.resumeTransformFeedback();
1772e5c31af7Sopenharmony_ci
1773e5c31af7Sopenharmony_ci		// Start the query, submit draw that results in feeding back exactly 1
1774e5c31af7Sopenharmony_ci		// triangles, then stop the query.
1775e5c31af7Sopenharmony_ci		drawTriangles(1);
1776e5c31af7Sopenharmony_ci
1777e5c31af7Sopenharmony_ci		// Call EndTransformFeedback.
1778e5c31af7Sopenharmony_ci		gl.endTransformFeedback();
1779e5c31af7Sopenharmony_ci
1780e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
1781e5c31af7Sopenharmony_ci		// query is TRUE.
1782e5c31af7Sopenharmony_ci		verifyQueryResults(GL_TRUE);
1783e5c31af7Sopenharmony_ci
1784e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1785e5c31af7Sopenharmony_ci
1786e5c31af7Sopenharmony_ci		return STOP;
1787e5c31af7Sopenharmony_ci	}
1788e5c31af7Sopenharmony_ci};
1789e5c31af7Sopenharmony_ci
1790e5c31af7Sopenharmony_ci/*
1791e5c31af7Sopenharmony_ci Base class for all multiple stream test cases.
1792e5c31af7Sopenharmony_ci */
1793e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryMultipleStreamsBase : public TransformFeedbackOverflowQueryFunctionalBase
1794e5c31af7Sopenharmony_ci{
1795e5c31af7Sopenharmony_ciprotected:
1796e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryMultipleStreamsBase(deqp::Context&						   context,
1797e5c31af7Sopenharmony_ci													  TransformFeedbackOverflowQueryTests::API api, const char* name,
1798e5c31af7Sopenharmony_ci													  const char* description)
1799e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQueryFunctionalBase(context, api, name, description)
1800e5c31af7Sopenharmony_ci	{
1801e5c31af7Sopenharmony_ci	}
1802e5c31af7Sopenharmony_ci
1803e5c31af7Sopenharmony_ci	/* Vertex shader to use for transform feedback. */
1804e5c31af7Sopenharmony_ci	virtual const char* transformFeedbackVertexShader()
1805e5c31af7Sopenharmony_ci	{
1806e5c31af7Sopenharmony_ci		return "#version 150 core\n"
1807e5c31af7Sopenharmony_ci			   "void main() {\n"
1808e5c31af7Sopenharmony_ci			   "}";
1809e5c31af7Sopenharmony_ci	}
1810e5c31af7Sopenharmony_ci
1811e5c31af7Sopenharmony_ci	/* Use interleaved attributes. */
1812e5c31af7Sopenharmony_ci	virtual GLenum bufferMode()
1813e5c31af7Sopenharmony_ci	{
1814e5c31af7Sopenharmony_ci		return GL_INTERLEAVED_ATTRIBS;
1815e5c31af7Sopenharmony_ci	}
1816e5c31af7Sopenharmony_ci
1817e5c31af7Sopenharmony_ci	/* Always use 4 transform feedback buffers. */
1818e5c31af7Sopenharmony_ci	virtual GLsizei bufferCount()
1819e5c31af7Sopenharmony_ci	{
1820e5c31af7Sopenharmony_ci		return 4;
1821e5c31af7Sopenharmony_ci	}
1822e5c31af7Sopenharmony_ci
1823e5c31af7Sopenharmony_ci	/* Draws a set of points to each vertex stream while having the overflow queries active. */
1824e5c31af7Sopenharmony_ci	void drawStreams(GLsizei count0, GLsizei count1 = 0, GLsizei count2 = 0, GLsizei count3 = 0)
1825e5c31af7Sopenharmony_ci	{
1826e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1827e5c31af7Sopenharmony_ci
1828e5c31af7Sopenharmony_ci		GLint streamLoc = gl.getUniformLocation(m_program, "stream");
1829e5c31af7Sopenharmony_ci
1830e5c31af7Sopenharmony_ci		beginQueries();
1831e5c31af7Sopenharmony_ci
1832e5c31af7Sopenharmony_ci		gl.uniform1ui(streamLoc, 0);
1833e5c31af7Sopenharmony_ci		gl.drawArrays(GL_POINTS, 0, count0);
1834e5c31af7Sopenharmony_ci
1835e5c31af7Sopenharmony_ci		gl.uniform1ui(streamLoc, 1);
1836e5c31af7Sopenharmony_ci		gl.drawArrays(GL_POINTS, 0, count1);
1837e5c31af7Sopenharmony_ci
1838e5c31af7Sopenharmony_ci		gl.uniform1ui(streamLoc, 2);
1839e5c31af7Sopenharmony_ci		gl.drawArrays(GL_POINTS, 0, count2);
1840e5c31af7Sopenharmony_ci
1841e5c31af7Sopenharmony_ci		gl.uniform1ui(streamLoc, 3);
1842e5c31af7Sopenharmony_ci		gl.drawArrays(GL_POINTS, 0, count3);
1843e5c31af7Sopenharmony_ci
1844e5c31af7Sopenharmony_ci		endQueries();
1845e5c31af7Sopenharmony_ci	}
1846e5c31af7Sopenharmony_ci};
1847e5c31af7Sopenharmony_ci
1848e5c31af7Sopenharmony_ci/*
1849e5c31af7Sopenharmony_ci Test case #5 - Advanced multiple streams, one buffer per stream.
1850e5c31af7Sopenharmony_ci */
1851e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryMultipleStreamsOneBufferPerStream
1852e5c31af7Sopenharmony_ci	: public TransformFeedbackOverflowQueryMultipleStreamsBase
1853e5c31af7Sopenharmony_ci{
1854e5c31af7Sopenharmony_cipublic:
1855e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryMultipleStreamsOneBufferPerStream(deqp::Context&							 context,
1856e5c31af7Sopenharmony_ci																	TransformFeedbackOverflowQueryTests::API api,
1857e5c31af7Sopenharmony_ci																	const char*								 name)
1858e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQueryMultipleStreamsBase(context, api, name,
1859e5c31af7Sopenharmony_ci															"Advanced multiple streams, one buffer per stream.")
1860e5c31af7Sopenharmony_ci	{
1861e5c31af7Sopenharmony_ci	}
1862e5c31af7Sopenharmony_ci
1863e5c31af7Sopenharmony_ci	/* Geometry shader to use for transform feedback. */
1864e5c31af7Sopenharmony_ci	virtual const char* transformFeedbackGeometryShader()
1865e5c31af7Sopenharmony_ci	{
1866e5c31af7Sopenharmony_ci		return "#version 150 core\n"
1867e5c31af7Sopenharmony_ci			   "#extension GL_ARB_gpu_shader5 : require\n"
1868e5c31af7Sopenharmony_ci			   "layout(points) in;\n"
1869e5c31af7Sopenharmony_ci			   "layout(points, max_vertices = 1) out;\n"
1870e5c31af7Sopenharmony_ci			   "layout(stream=0) out float output1;\n"
1871e5c31af7Sopenharmony_ci			   "layout(stream=1) out float output2;\n"
1872e5c31af7Sopenharmony_ci			   "layout(stream=2) out float output3;\n"
1873e5c31af7Sopenharmony_ci			   "layout(stream=3) out float output4;\n"
1874e5c31af7Sopenharmony_ci			   "uniform uint stream;\n"
1875e5c31af7Sopenharmony_ci			   "void main() {\n"
1876e5c31af7Sopenharmony_ci			   "    if (stream == 0) {\n"
1877e5c31af7Sopenharmony_ci			   "        output1 = 1.0;\n"
1878e5c31af7Sopenharmony_ci			   "        EmitStreamVertex(0);\n"
1879e5c31af7Sopenharmony_ci			   "        EndStreamPrimitive(0);\n"
1880e5c31af7Sopenharmony_ci			   "    }\n"
1881e5c31af7Sopenharmony_ci			   "    if (stream == 1) {\n"
1882e5c31af7Sopenharmony_ci			   "        output2 = 2.0;\n"
1883e5c31af7Sopenharmony_ci			   "        EmitStreamVertex(1);\n"
1884e5c31af7Sopenharmony_ci			   "        EndStreamPrimitive(1);\n"
1885e5c31af7Sopenharmony_ci			   "    }\n"
1886e5c31af7Sopenharmony_ci			   "    if (stream == 2) {\n"
1887e5c31af7Sopenharmony_ci			   "        output3 = 3.0;\n"
1888e5c31af7Sopenharmony_ci			   "        EmitStreamVertex(2);\n"
1889e5c31af7Sopenharmony_ci			   "        EndStreamPrimitive(2);\n"
1890e5c31af7Sopenharmony_ci			   "    }\n"
1891e5c31af7Sopenharmony_ci			   "    if (stream == 3) {\n"
1892e5c31af7Sopenharmony_ci			   "        output4 = 4.0;\n"
1893e5c31af7Sopenharmony_ci			   "        EmitStreamVertex(3);\n"
1894e5c31af7Sopenharmony_ci			   "        EndStreamPrimitive(3);\n"
1895e5c31af7Sopenharmony_ci			   "    }\n"
1896e5c31af7Sopenharmony_ci			   "}";
1897e5c31af7Sopenharmony_ci	}
1898e5c31af7Sopenharmony_ci
1899e5c31af7Sopenharmony_ci	/* Together with the separators there are a total of 7 varyings. */
1900e5c31af7Sopenharmony_ci	virtual GLsizei varyingsCount()
1901e5c31af7Sopenharmony_ci	{
1902e5c31af7Sopenharmony_ci		return 7;
1903e5c31af7Sopenharmony_ci	}
1904e5c31af7Sopenharmony_ci
1905e5c31af7Sopenharmony_ci	/* Each output goes to different buffer. The mapping between vertex stream outputs and transform feedback buffers is non-identity. */
1906e5c31af7Sopenharmony_ci	virtual const char** varyings()
1907e5c31af7Sopenharmony_ci	{
1908e5c31af7Sopenharmony_ci		static const char* vars[] = { "output4", "gl_NextBuffer", "output3", "gl_NextBuffer",
1909e5c31af7Sopenharmony_ci									  "output2", "gl_NextBuffer", "output1" };
1910e5c31af7Sopenharmony_ci		return vars;
1911e5c31af7Sopenharmony_ci	}
1912e5c31af7Sopenharmony_ci
1913e5c31af7Sopenharmony_ci	/* The size of the transform feedback buffers should be enough to be able to capture exactly 10 vertices for each vertex stream. */
1914e5c31af7Sopenharmony_ci	virtual GLsizei bufferSize(GLint index)
1915e5c31af7Sopenharmony_ci	{
1916e5c31af7Sopenharmony_ci		(void)index;
1917e5c31af7Sopenharmony_ci		return 10 * sizeof(GLfloat);
1918e5c31af7Sopenharmony_ci	}
1919e5c31af7Sopenharmony_ci
1920e5c31af7Sopenharmony_ci	/* Test case iterate function. Contains the actual test case logic. */
1921e5c31af7Sopenharmony_ci	IterateResult iterate()
1922e5c31af7Sopenharmony_ci	{
1923e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1924e5c31af7Sopenharmony_ci
1925e5c31af7Sopenharmony_ci		// If GL 4.0 and ARB_transform_feedback3 are not supported then skip this
1926e5c31af7Sopenharmony_ci		// test case.
1927e5c31af7Sopenharmony_ci		if (!supportsTransformFeedback3())
1928e5c31af7Sopenharmony_ci		{
1929e5c31af7Sopenharmony_ci			throw tcu::NotSupportedError("Required transform_feedback3 extension is not supported");
1930e5c31af7Sopenharmony_ci		}
1931e5c31af7Sopenharmony_ci
1932e5c31af7Sopenharmony_ci		// If GL 4.0 and ARB_gpu_shader5 are not supported then skip this
1933e5c31af7Sopenharmony_ci		// test case.
1934e5c31af7Sopenharmony_ci		if (!supportsGpuShader5())
1935e5c31af7Sopenharmony_ci		{
1936e5c31af7Sopenharmony_ci			throw tcu::NotSupportedError("Required gpu_shader5 extension is not supported");
1937e5c31af7Sopenharmony_ci		}
1938e5c31af7Sopenharmony_ci
1939e5c31af7Sopenharmony_ci		// Call BeginTransformFeedback with mode POINTS.
1940e5c31af7Sopenharmony_ci		gl.beginTransformFeedback(GL_POINTS);
1941e5c31af7Sopenharmony_ci
1942e5c31af7Sopenharmony_ci		// Start all queries, submit draw that results in feeding back exactly 8
1943e5c31af7Sopenharmony_ci		// points for all four vertex streams, then stop the queries.
1944e5c31af7Sopenharmony_ci		drawStreams(8, 8, 8, 8);
1945e5c31af7Sopenharmony_ci
1946e5c31af7Sopenharmony_ci		// Call PauseTransformFeedback.
1947e5c31af7Sopenharmony_ci		gl.pauseTransformFeedback();
1948e5c31af7Sopenharmony_ci
1949e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
1950e5c31af7Sopenharmony_ci		// queries are all FALSE.
1951e5c31af7Sopenharmony_ci		verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1952e5c31af7Sopenharmony_ci
1953e5c31af7Sopenharmony_ci		// Start the queries, submit draw that would result in feeding back more
1954e5c31af7Sopenharmony_ci		// than 10 points for all four vertex streams if transform feedback wasn't
1955e5c31af7Sopenharmony_ci		// paused, then stop the queries.
1956e5c31af7Sopenharmony_ci		drawStreams(11, 11, 11, 11);
1957e5c31af7Sopenharmony_ci
1958e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
1959e5c31af7Sopenharmony_ci		// queries are all FALSE.
1960e5c31af7Sopenharmony_ci		verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1961e5c31af7Sopenharmony_ci
1962e5c31af7Sopenharmony_ci		// Call ResumeTransformFeedback.
1963e5c31af7Sopenharmony_ci		gl.resumeTransformFeedback();
1964e5c31af7Sopenharmony_ci
1965e5c31af7Sopenharmony_ci		// Start the queries, submit draw that results in feeding back exactly 3
1966e5c31af7Sopenharmony_ci		// points only for vertex streams #1 and #3, then stop the queries.
1967e5c31af7Sopenharmony_ci		drawStreams(0, 3, 0, 3);
1968e5c31af7Sopenharmony_ci
1969e5c31af7Sopenharmony_ci		// Call PauseTransformFeedback.
1970e5c31af7Sopenharmony_ci		gl.pauseTransformFeedback();
1971e5c31af7Sopenharmony_ci
1972e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
1973e5c31af7Sopenharmony_ci		// queries are all FALSE, except for the TRANSFORM_FEEDBACK_OVERFLOW
1974e5c31af7Sopenharmony_ci		// query, and the TRANSFORM_FEEDBACK_STREAM_OVERFLOW queries for
1975e5c31af7Sopenharmony_ci		// vertex streams #1 and #3, which should have a TRUE result.
1976e5c31af7Sopenharmony_ci		verifyQueryResults(GL_TRUE, GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
1977e5c31af7Sopenharmony_ci
1978e5c31af7Sopenharmony_ci		// Call ResumeTransformFeedback.
1979e5c31af7Sopenharmony_ci		gl.resumeTransformFeedback();
1980e5c31af7Sopenharmony_ci
1981e5c31af7Sopenharmony_ci		// Start the queries, submit draw that results in feeding back exactly 2
1982e5c31af7Sopenharmony_ci		// points only for vertex streams #0 and #2, then stop the queries.
1983e5c31af7Sopenharmony_ci		drawStreams(2, 0, 2, 0);
1984e5c31af7Sopenharmony_ci
1985e5c31af7Sopenharmony_ci		// Call PauseTransformFeedback.
1986e5c31af7Sopenharmony_ci		gl.pauseTransformFeedback();
1987e5c31af7Sopenharmony_ci
1988e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
1989e5c31af7Sopenharmony_ci		// queries are all FALSE.
1990e5c31af7Sopenharmony_ci		verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1991e5c31af7Sopenharmony_ci
1992e5c31af7Sopenharmony_ci		// Call ResumeTransformFeedback.
1993e5c31af7Sopenharmony_ci		gl.resumeTransformFeedback();
1994e5c31af7Sopenharmony_ci
1995e5c31af7Sopenharmony_ci		// Start the queries, submit draw that results in feeding back exactly 1
1996e5c31af7Sopenharmony_ci		// point for vertex streams #2 and #3, then stop the queries.
1997e5c31af7Sopenharmony_ci		drawStreams(0, 0, 1, 1);
1998e5c31af7Sopenharmony_ci
1999e5c31af7Sopenharmony_ci		// Call EndTransformFeedback.
2000e5c31af7Sopenharmony_ci		gl.endTransformFeedback();
2001e5c31af7Sopenharmony_ci
2002e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
2003e5c31af7Sopenharmony_ci		// queries are all FALSE, except for the TRANSFORM_FEEDBACK_OVERFLOW
2004e5c31af7Sopenharmony_ci		// query, and the TRANSFORM_FEEDBACK_STREAM_OVERFLOW queries for
2005e5c31af7Sopenharmony_ci		// vertex streams #2 and #3, which should have a TRUE result.
2006e5c31af7Sopenharmony_ci		verifyQueryResults(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE);
2007e5c31af7Sopenharmony_ci
2008e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2009e5c31af7Sopenharmony_ci
2010e5c31af7Sopenharmony_ci		return STOP;
2011e5c31af7Sopenharmony_ci	}
2012e5c31af7Sopenharmony_ci};
2013e5c31af7Sopenharmony_ci
2014e5c31af7Sopenharmony_ci/*
2015e5c31af7Sopenharmony_ci Test case #6 - Advanced multiple streams, multiple buffers per stream.
2016e5c31af7Sopenharmony_ci */
2017e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryMultipleStreamsMultipleBufferPerStream
2018e5c31af7Sopenharmony_ci	: public TransformFeedbackOverflowQueryMultipleStreamsBase
2019e5c31af7Sopenharmony_ci{
2020e5c31af7Sopenharmony_cipublic:
2021e5c31af7Sopenharmony_ci	TransformFeedbackOverflowQueryMultipleStreamsMultipleBufferPerStream(deqp::Context& context,
2022e5c31af7Sopenharmony_ci																		 TransformFeedbackOverflowQueryTests::API api,
2023e5c31af7Sopenharmony_ci																		 const char*							  name)
2024e5c31af7Sopenharmony_ci		: TransformFeedbackOverflowQueryMultipleStreamsBase(context, api, name,
2025e5c31af7Sopenharmony_ci															"Advanced multiple streams, multiple buffers per stream.")
2026e5c31af7Sopenharmony_ci	{
2027e5c31af7Sopenharmony_ci	}
2028e5c31af7Sopenharmony_ci
2029e5c31af7Sopenharmony_ci	/* Geometry shader to use for transform feedback. */
2030e5c31af7Sopenharmony_ci	virtual const char* transformFeedbackGeometryShader()
2031e5c31af7Sopenharmony_ci	{
2032e5c31af7Sopenharmony_ci		return "#version 150 core\n"
2033e5c31af7Sopenharmony_ci			   "#extension GL_ARB_gpu_shader5 : require\n"
2034e5c31af7Sopenharmony_ci			   "layout(points) in;\n"
2035e5c31af7Sopenharmony_ci			   "layout(points, max_vertices = 1) out;\n"
2036e5c31af7Sopenharmony_ci			   "layout(stream=0) out float output1;\n"
2037e5c31af7Sopenharmony_ci			   "layout(stream=0) out float output2;\n"
2038e5c31af7Sopenharmony_ci			   "layout(stream=1) out float output3;\n"
2039e5c31af7Sopenharmony_ci			   "layout(stream=1) out float output4;\n"
2040e5c31af7Sopenharmony_ci			   "uniform uint stream;\n"
2041e5c31af7Sopenharmony_ci			   "void main() {\n"
2042e5c31af7Sopenharmony_ci			   "    if (stream == 0) {\n"
2043e5c31af7Sopenharmony_ci			   "        output1 = 1.0;\n"
2044e5c31af7Sopenharmony_ci			   "        output2 = 2.0;\n"
2045e5c31af7Sopenharmony_ci			   "        EmitStreamVertex(0);\n"
2046e5c31af7Sopenharmony_ci			   "        EndStreamPrimitive(0);\n"
2047e5c31af7Sopenharmony_ci			   "    }\n"
2048e5c31af7Sopenharmony_ci			   "    if (stream == 1) {\n"
2049e5c31af7Sopenharmony_ci			   "        output3 = 3.0;\n"
2050e5c31af7Sopenharmony_ci			   "        output4 = 4.0;\n"
2051e5c31af7Sopenharmony_ci			   "        EmitStreamVertex(1);\n"
2052e5c31af7Sopenharmony_ci			   "        EndStreamPrimitive(1);\n"
2053e5c31af7Sopenharmony_ci			   "    }\n"
2054e5c31af7Sopenharmony_ci			   "}";
2055e5c31af7Sopenharmony_ci	}
2056e5c31af7Sopenharmony_ci
2057e5c31af7Sopenharmony_ci	/* Together with the separators there are a total of 7 varyings. */
2058e5c31af7Sopenharmony_ci	virtual GLsizei varyingsCount()
2059e5c31af7Sopenharmony_ci	{
2060e5c31af7Sopenharmony_ci		return 7;
2061e5c31af7Sopenharmony_ci	}
2062e5c31af7Sopenharmony_ci
2063e5c31af7Sopenharmony_ci	/* Vertex stream #0 is captured by transform feedback buffers #1 and #2, while
2064e5c31af7Sopenharmony_ci	 vertex stream #1 is captured by transform feedback buffers #3 and #0. */
2065e5c31af7Sopenharmony_ci	virtual const char** varyings()
2066e5c31af7Sopenharmony_ci	{
2067e5c31af7Sopenharmony_ci		static const char* vars[] = { "output4", "gl_NextBuffer", "output1", "gl_NextBuffer",
2068e5c31af7Sopenharmony_ci									  "output2", "gl_NextBuffer", "output3" };
2069e5c31af7Sopenharmony_ci		return vars;
2070e5c31af7Sopenharmony_ci	}
2071e5c31af7Sopenharmony_ci
2072e5c31af7Sopenharmony_ci	/* Transform feedback buffers #0 and #1 should be able to capture exactly 10 vertices, while
2073e5c31af7Sopenharmony_ci	 transform feedback buffers #2 and #3 should be able to capture exactly 20 vertices. */
2074e5c31af7Sopenharmony_ci	virtual GLsizei bufferSize(GLint index)
2075e5c31af7Sopenharmony_ci	{
2076e5c31af7Sopenharmony_ci		if (index < 2)
2077e5c31af7Sopenharmony_ci		{
2078e5c31af7Sopenharmony_ci			return 10 * sizeof(GLfloat);
2079e5c31af7Sopenharmony_ci		}
2080e5c31af7Sopenharmony_ci		else
2081e5c31af7Sopenharmony_ci		{
2082e5c31af7Sopenharmony_ci			return 20 * sizeof(GLfloat);
2083e5c31af7Sopenharmony_ci		}
2084e5c31af7Sopenharmony_ci	}
2085e5c31af7Sopenharmony_ci
2086e5c31af7Sopenharmony_ci	/* Test case iterate function. Contains the actual test case logic. */
2087e5c31af7Sopenharmony_ci	IterateResult iterate()
2088e5c31af7Sopenharmony_ci	{
2089e5c31af7Sopenharmony_ci		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2090e5c31af7Sopenharmony_ci
2091e5c31af7Sopenharmony_ci		// If GL 4.0 and ARB_transform_feedback3 are not supported then skip this
2092e5c31af7Sopenharmony_ci		// test case.
2093e5c31af7Sopenharmony_ci		if (!supportsTransformFeedback3())
2094e5c31af7Sopenharmony_ci		{
2095e5c31af7Sopenharmony_ci			throw tcu::NotSupportedError("Required transform_feedback3 extension is not supported");
2096e5c31af7Sopenharmony_ci		}
2097e5c31af7Sopenharmony_ci
2098e5c31af7Sopenharmony_ci		// If GL 4.0 and ARB_gpu_shader5 are not supported then skip this
2099e5c31af7Sopenharmony_ci		// test case.
2100e5c31af7Sopenharmony_ci		if (!supportsGpuShader5())
2101e5c31af7Sopenharmony_ci		{
2102e5c31af7Sopenharmony_ci			throw tcu::NotSupportedError("Required gpu_shader5 extension is not supported");
2103e5c31af7Sopenharmony_ci		}
2104e5c31af7Sopenharmony_ci
2105e5c31af7Sopenharmony_ci		// Call BeginTransformFeedback with mode POINTS.
2106e5c31af7Sopenharmony_ci		gl.beginTransformFeedback(GL_POINTS);
2107e5c31af7Sopenharmony_ci
2108e5c31af7Sopenharmony_ci		// Start all queries, submit draw that results in feeding back exactly 8
2109e5c31af7Sopenharmony_ci		// points to both vertex streams, then stop the queries.
2110e5c31af7Sopenharmony_ci		drawStreams(8, 8);
2111e5c31af7Sopenharmony_ci
2112e5c31af7Sopenharmony_ci		// Call PauseTransformFeedback.
2113e5c31af7Sopenharmony_ci		gl.pauseTransformFeedback();
2114e5c31af7Sopenharmony_ci
2115e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
2116e5c31af7Sopenharmony_ci		// queries are all FALSE.
2117e5c31af7Sopenharmony_ci		verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE);
2118e5c31af7Sopenharmony_ci
2119e5c31af7Sopenharmony_ci		// Start the queries, submit draw that would result in feeding back more
2120e5c31af7Sopenharmony_ci		// than 10 points for both vertex streams if transform feedback wasn't
2121e5c31af7Sopenharmony_ci		// paused, then stop the queries.
2122e5c31af7Sopenharmony_ci		drawStreams(11, 11);
2123e5c31af7Sopenharmony_ci
2124e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
2125e5c31af7Sopenharmony_ci		// queries are all FALSE.
2126e5c31af7Sopenharmony_ci		verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE);
2127e5c31af7Sopenharmony_ci
2128e5c31af7Sopenharmony_ci		// Call ResumeTransformFeedback.
2129e5c31af7Sopenharmony_ci		gl.resumeTransformFeedback();
2130e5c31af7Sopenharmony_ci
2131e5c31af7Sopenharmony_ci		// Start the queries, submit draw that results in feeding back exactly 1
2132e5c31af7Sopenharmony_ci		// point for vertex stream #0 and exactly 3 points for vertex stream #1,
2133e5c31af7Sopenharmony_ci		// then stop the queries.
2134e5c31af7Sopenharmony_ci		drawStreams(1, 3);
2135e5c31af7Sopenharmony_ci
2136e5c31af7Sopenharmony_ci		// Call PauseTransformFeedback.
2137e5c31af7Sopenharmony_ci		gl.pauseTransformFeedback();
2138e5c31af7Sopenharmony_ci
2139e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
2140e5c31af7Sopenharmony_ci		// queries are all FALSE, except for the TRANSFORM_FEEDBACK_OVERFLOW
2141e5c31af7Sopenharmony_ci		// query, and the TRANSFORM_FEEDBACK_STREAM_OVERFLOW query for vertex
2142e5c31af7Sopenharmony_ci		// stream #1, which should have a TRUE result.
2143e5c31af7Sopenharmony_ci		verifyQueryResults(GL_TRUE, GL_FALSE, GL_TRUE);
2144e5c31af7Sopenharmony_ci
2145e5c31af7Sopenharmony_ci		// Call ResumeTransformFeedback.
2146e5c31af7Sopenharmony_ci		gl.resumeTransformFeedback();
2147e5c31af7Sopenharmony_ci
2148e5c31af7Sopenharmony_ci		// Start the queries, submit draw that results in feeding back exactly 1
2149e5c31af7Sopenharmony_ci		// point only for vertex stream #0, then stop the queries.
2150e5c31af7Sopenharmony_ci		drawStreams(1, 0);
2151e5c31af7Sopenharmony_ci
2152e5c31af7Sopenharmony_ci		// Call PauseTransformFeedback.
2153e5c31af7Sopenharmony_ci		gl.pauseTransformFeedback();
2154e5c31af7Sopenharmony_ci
2155e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
2156e5c31af7Sopenharmony_ci		// queries are all FALSE.
2157e5c31af7Sopenharmony_ci		verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE);
2158e5c31af7Sopenharmony_ci
2159e5c31af7Sopenharmony_ci		// Call ResumeTransformFeedback.
2160e5c31af7Sopenharmony_ci		gl.resumeTransformFeedback();
2161e5c31af7Sopenharmony_ci
2162e5c31af7Sopenharmony_ci		// Start the queries, submit draw that results in feeding back exactly 1
2163e5c31af7Sopenharmony_ci		// point for vertex streams #0 and #1, then stop the queries.
2164e5c31af7Sopenharmony_ci		drawStreams(1, 1);
2165e5c31af7Sopenharmony_ci
2166e5c31af7Sopenharmony_ci		// Call EndTransformFeedback.
2167e5c31af7Sopenharmony_ci		gl.endTransformFeedback();
2168e5c31af7Sopenharmony_ci
2169e5c31af7Sopenharmony_ci		// Use the basic checking mechanism to validate that the result of the
2170e5c31af7Sopenharmony_ci		// queries are all FALSE, except for the TRANSFORM_FEEDBACK_OVERFLOW
2171e5c31af7Sopenharmony_ci		// query, and the TRANSFORM_FEEDBACK_STREAM_OVERFLOW queries for
2172e5c31af7Sopenharmony_ci		// vertex streams #0 and #1, which should have a TRUE result.
2173e5c31af7Sopenharmony_ci		verifyQueryResults(GL_TRUE, GL_TRUE, GL_TRUE);
2174e5c31af7Sopenharmony_ci
2175e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2176e5c31af7Sopenharmony_ci
2177e5c31af7Sopenharmony_ci		return STOP;
2178e5c31af7Sopenharmony_ci	}
2179e5c31af7Sopenharmony_ci};
2180e5c31af7Sopenharmony_ci
2181e5c31af7Sopenharmony_ciconst char* apiToTestName(TransformFeedbackOverflowQueryTests::API api)
2182e5c31af7Sopenharmony_ci{
2183e5c31af7Sopenharmony_ci	switch (api)
2184e5c31af7Sopenharmony_ci	{
2185e5c31af7Sopenharmony_ci	case TransformFeedbackOverflowQueryTests::API_GL_ARB_transform_feedback_overflow_query:
2186e5c31af7Sopenharmony_ci		return "transform_feedback_overflow_query_ARB";
2187e5c31af7Sopenharmony_ci	}
2188e5c31af7Sopenharmony_ci	DE_ASSERT(0);
2189e5c31af7Sopenharmony_ci	return "";
2190e5c31af7Sopenharmony_ci}
2191e5c31af7Sopenharmony_ci
2192e5c31af7Sopenharmony_ci/** Constructor.
2193e5c31af7Sopenharmony_ci *
2194e5c31af7Sopenharmony_ci *  @param context Rendering context.
2195e5c31af7Sopenharmony_ci *  @param api     API to test (core vs ARB extension)
2196e5c31af7Sopenharmony_ci **/
2197e5c31af7Sopenharmony_ciTransformFeedbackOverflowQueryTests::TransformFeedbackOverflowQueryTests(deqp::Context& context, API api)
2198e5c31af7Sopenharmony_ci	: TestCaseGroup(context, apiToTestName(api), "Verifies \"transform_feedback_overflow_query\" functionality")
2199e5c31af7Sopenharmony_ci	, m_api(api)
2200e5c31af7Sopenharmony_ci{
2201e5c31af7Sopenharmony_ci	/* Left blank on purpose */
2202e5c31af7Sopenharmony_ci}
2203e5c31af7Sopenharmony_ci
2204e5c31af7Sopenharmony_ci/** Destructor.
2205e5c31af7Sopenharmony_ci *
2206e5c31af7Sopenharmony_ci **/
2207e5c31af7Sopenharmony_ciTransformFeedbackOverflowQueryTests::~TransformFeedbackOverflowQueryTests()
2208e5c31af7Sopenharmony_ci{
2209e5c31af7Sopenharmony_ci}
2210e5c31af7Sopenharmony_ci
2211e5c31af7Sopenharmony_ci/** Initializes the texture_barrier test group.
2212e5c31af7Sopenharmony_ci *
2213e5c31af7Sopenharmony_ci **/
2214e5c31af7Sopenharmony_civoid TransformFeedbackOverflowQueryTests::init(void)
2215e5c31af7Sopenharmony_ci{
2216e5c31af7Sopenharmony_ci	addChild(new TransformFeedbackOverflowQueryImplDepState(m_context, m_api, "implementation-dependent-state"));
2217e5c31af7Sopenharmony_ci	addChild(new TransformFeedbackOverflowQueryDefaultState(m_context, m_api, "default-context-state"));
2218e5c31af7Sopenharmony_ci	addChild(new TransformFeedbackOverflowQueryStateUpdate(m_context, m_api, "context-state-update"));
2219e5c31af7Sopenharmony_ci	addChild(new TransformFeedbackOverflowQueryErrorInvalidIndex(m_context, m_api, "error-invalid-index"));
2220e5c31af7Sopenharmony_ci	addChild(new TransformFeedbackOverflowQueryErrorAlreadyActive(m_context, m_api, "error-already-active"));
2221e5c31af7Sopenharmony_ci	addChild(new TransformFeedbackOverflowQueryErrorIncompatibleTarget(m_context, m_api, "error-incompatible-target"));
2222e5c31af7Sopenharmony_ci	addChild(new TransformFeedbackOverflowQueryErrorNoActiveQuery(m_context, m_api, "error-no-active-query"));
2223e5c31af7Sopenharmony_ci	addChild(new TransformFeedbackOverflowQueryBasicSingleStreamInterleavedAttribs(
2224e5c31af7Sopenharmony_ci		m_context, m_api, "basic-single-stream-interleaved-attribs"));
2225e5c31af7Sopenharmony_ci	addChild(new TransformFeedbackOverflowQueryBasicSingleStreamSeparateAttribs(
2226e5c31af7Sopenharmony_ci		m_context, m_api, "basic-single-stream-separate-attribs"));
2227e5c31af7Sopenharmony_ci	addChild(new TransformFeedbackOverflowQueryAdvancedSingleStreamInterleavedAttribs(
2228e5c31af7Sopenharmony_ci		m_context, m_api, "advanced-single-stream-interleaved-attribs"));
2229e5c31af7Sopenharmony_ci	addChild(new TransformFeedbackOverflowQueryAdvancedSingleStreamSeparateAttribs(
2230e5c31af7Sopenharmony_ci		m_context, m_api, "advanced-single-stream-separate-attribs"));
2231e5c31af7Sopenharmony_ci	addChild(new TransformFeedbackOverflowQueryMultipleStreamsOneBufferPerStream(
2232e5c31af7Sopenharmony_ci		m_context, m_api, "multiple-streams-one-buffer-per-stream"));
2233e5c31af7Sopenharmony_ci	addChild(new TransformFeedbackOverflowQueryMultipleStreamsMultipleBufferPerStream(
2234e5c31af7Sopenharmony_ci		m_context, m_api, "multiple-streams-multiple-buffers-per-stream"));
2235e5c31af7Sopenharmony_ci}
2236e5c31af7Sopenharmony_ci} /* glcts namespace */
2237