1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES 3.0 Module
3e5c31af7Sopenharmony_ci * -------------------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project
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 Long running shader stress tests.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "es3sLongRunningShaderTests.hpp"
25e5c31af7Sopenharmony_ci
26e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp"
27e5c31af7Sopenharmony_ci#include "gluShaderUtil.hpp"
28e5c31af7Sopenharmony_ci#include "gluDrawUtil.hpp"
29e5c31af7Sopenharmony_ci
30e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp"
31e5c31af7Sopenharmony_ci#include "tcuVector.hpp"
32e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp"
33e5c31af7Sopenharmony_ci
34e5c31af7Sopenharmony_ci#include "deRandom.hpp"
35e5c31af7Sopenharmony_ci#include "deStringUtil.hpp"
36e5c31af7Sopenharmony_ci#include "deString.h"
37e5c31af7Sopenharmony_ci
38e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
39e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
40e5c31af7Sopenharmony_ci
41e5c31af7Sopenharmony_cinamespace deqp
42e5c31af7Sopenharmony_ci{
43e5c31af7Sopenharmony_cinamespace gles3
44e5c31af7Sopenharmony_ci{
45e5c31af7Sopenharmony_cinamespace Stress
46e5c31af7Sopenharmony_ci{
47e5c31af7Sopenharmony_ci
48e5c31af7Sopenharmony_ciusing tcu::TestLog;
49e5c31af7Sopenharmony_ciusing tcu::Vec2;
50e5c31af7Sopenharmony_ciusing std::vector;
51e5c31af7Sopenharmony_ci
52e5c31af7Sopenharmony_cinamespace
53e5c31af7Sopenharmony_ci{
54e5c31af7Sopenharmony_ci
55e5c31af7Sopenharmony_cienum LoopType
56e5c31af7Sopenharmony_ci{
57e5c31af7Sopenharmony_ci	LOOPTYPE_FOR = 0,
58e5c31af7Sopenharmony_ci	LOOPTYPE_WHILE,
59e5c31af7Sopenharmony_ci	LOOPTYPE_DO_WHILE,
60e5c31af7Sopenharmony_ci
61e5c31af7Sopenharmony_ci	LOOPTYPE_LAST
62e5c31af7Sopenharmony_ci};
63e5c31af7Sopenharmony_ci
64e5c31af7Sopenharmony_cienum IterCountType
65e5c31af7Sopenharmony_ci{
66e5c31af7Sopenharmony_ci	ITERCOUNTTYPE_STATIC = 0,
67e5c31af7Sopenharmony_ci	ITERCOUNTTYPE_UNIFORM,
68e5c31af7Sopenharmony_ci	ITERCOUNTTYPE_DYNAMIC,
69e5c31af7Sopenharmony_ci
70e5c31af7Sopenharmony_ci	ITERCOUNTTYPE_LAST
71e5c31af7Sopenharmony_ci};
72e5c31af7Sopenharmony_ci
73e5c31af7Sopenharmony_ciclass LongRunningShaderCase : public TestCase
74e5c31af7Sopenharmony_ci{
75e5c31af7Sopenharmony_cipublic:
76e5c31af7Sopenharmony_ci	struct Params
77e5c31af7Sopenharmony_ci	{
78e5c31af7Sopenharmony_ci		const char*			name;
79e5c31af7Sopenharmony_ci		const char*			description;
80e5c31af7Sopenharmony_ci		glu::ShaderType		shaderType;
81e5c31af7Sopenharmony_ci		LoopType			loopType;
82e5c31af7Sopenharmony_ci		IterCountType		iterCountType;
83e5c31af7Sopenharmony_ci		int					numInvocations;
84e5c31af7Sopenharmony_ci		int					minLoopIterCount;
85e5c31af7Sopenharmony_ci		int					maxLoopIterCount;
86e5c31af7Sopenharmony_ci	};
87e5c31af7Sopenharmony_ci
88e5c31af7Sopenharmony_ci								LongRunningShaderCase		(Context& context, const Params* params);
89e5c31af7Sopenharmony_ci								~LongRunningShaderCase		(void);
90e5c31af7Sopenharmony_ci
91e5c31af7Sopenharmony_ci	void						init						(void);
92e5c31af7Sopenharmony_ci	void						deinit						(void);
93e5c31af7Sopenharmony_ci	IterateResult				iterate						(void);
94e5c31af7Sopenharmony_ci
95e5c31af7Sopenharmony_ciprivate:
96e5c31af7Sopenharmony_ci								LongRunningShaderCase		(const LongRunningShaderCase&);
97e5c31af7Sopenharmony_ci	LongRunningShaderCase&		operator=					(const LongRunningShaderCase&);
98e5c31af7Sopenharmony_ci
99e5c31af7Sopenharmony_ci	static glu::ProgramSources	genSources					(const Params& params);
100e5c31af7Sopenharmony_ci	static deUint32				getSeed						(const Params& params);
101e5c31af7Sopenharmony_ci
102e5c31af7Sopenharmony_ci	const Params* const			m_params;
103e5c31af7Sopenharmony_ci	const int					m_numCaseIters;
104e5c31af7Sopenharmony_ci
105e5c31af7Sopenharmony_ci	glu::ShaderProgram*			m_program;
106e5c31af7Sopenharmony_ci	int							m_caseIterNdx;
107e5c31af7Sopenharmony_ci};
108e5c31af7Sopenharmony_ci
109e5c31af7Sopenharmony_ciLongRunningShaderCase::LongRunningShaderCase (Context& context, const Params* params)
110e5c31af7Sopenharmony_ci	: TestCase			(context, params->name, params->description)
111e5c31af7Sopenharmony_ci	, m_params			(params)
112e5c31af7Sopenharmony_ci	, m_numCaseIters	(5)
113e5c31af7Sopenharmony_ci	, m_program			(DE_NULL)
114e5c31af7Sopenharmony_ci	, m_caseIterNdx		(0)
115e5c31af7Sopenharmony_ci{
116e5c31af7Sopenharmony_ci}
117e5c31af7Sopenharmony_ci
118e5c31af7Sopenharmony_ciLongRunningShaderCase::~LongRunningShaderCase (void)
119e5c31af7Sopenharmony_ci{
120e5c31af7Sopenharmony_ci	deinit();
121e5c31af7Sopenharmony_ci}
122e5c31af7Sopenharmony_ci
123e5c31af7Sopenharmony_ciglu::ProgramSources LongRunningShaderCase::genSources (const Params& params)
124e5c31af7Sopenharmony_ci{
125e5c31af7Sopenharmony_ci	const bool			isVertCase		= params.shaderType == glu::SHADERTYPE_VERTEX;
126e5c31af7Sopenharmony_ci	std::ostringstream	vert, frag;
127e5c31af7Sopenharmony_ci
128e5c31af7Sopenharmony_ci	vert << "#version 300 es\n"
129e5c31af7Sopenharmony_ci		 << "in highp vec2 a_position;\n";
130e5c31af7Sopenharmony_ci
131e5c31af7Sopenharmony_ci	frag << "#version 300 es\n";
132e5c31af7Sopenharmony_ci
133e5c31af7Sopenharmony_ci	if (params.iterCountType == ITERCOUNTTYPE_DYNAMIC)
134e5c31af7Sopenharmony_ci	{
135e5c31af7Sopenharmony_ci		vert << "in highp int a_iterCount;\n";
136e5c31af7Sopenharmony_ci		if (!isVertCase)
137e5c31af7Sopenharmony_ci		{
138e5c31af7Sopenharmony_ci			vert << "flat out highp int v_iterCount;\n";
139e5c31af7Sopenharmony_ci			frag << "flat in highp int v_iterCount;\n";
140e5c31af7Sopenharmony_ci		}
141e5c31af7Sopenharmony_ci	}
142e5c31af7Sopenharmony_ci	else if (params.iterCountType == ITERCOUNTTYPE_UNIFORM)
143e5c31af7Sopenharmony_ci		(isVertCase ? vert : frag) << "uniform highp int u_iterCount;\n";
144e5c31af7Sopenharmony_ci
145e5c31af7Sopenharmony_ci	if (isVertCase)
146e5c31af7Sopenharmony_ci	{
147e5c31af7Sopenharmony_ci		vert << "out mediump vec4 v_color;\n";
148e5c31af7Sopenharmony_ci		frag << "in mediump vec4 v_color;\n";
149e5c31af7Sopenharmony_ci	}
150e5c31af7Sopenharmony_ci
151e5c31af7Sopenharmony_ci	frag << "out mediump vec4 o_color;\n";
152e5c31af7Sopenharmony_ci
153e5c31af7Sopenharmony_ci	vert << "\nvoid main (void)\n{\n"
154e5c31af7Sopenharmony_ci		 << "	gl_Position = vec4(a_position, 0.0, 1.0);\n"
155e5c31af7Sopenharmony_ci		 << "	gl_PointSize = 1.0;\n";
156e5c31af7Sopenharmony_ci
157e5c31af7Sopenharmony_ci	if (!isVertCase && params.iterCountType == ITERCOUNTTYPE_DYNAMIC)
158e5c31af7Sopenharmony_ci		vert << "	v_iterCount = a_iterCount;\n";
159e5c31af7Sopenharmony_ci
160e5c31af7Sopenharmony_ci	frag << "\nvoid main (void)\n{\n";
161e5c31af7Sopenharmony_ci
162e5c31af7Sopenharmony_ci	{
163e5c31af7Sopenharmony_ci		const std::string	iterCount	= params.iterCountType == ITERCOUNTTYPE_DYNAMIC ? (isVertCase ? "a_iterCount" : "v_iterCount")	:
164e5c31af7Sopenharmony_ci										  params.iterCountType == ITERCOUNTTYPE_UNIFORM ? "u_iterCount"									:
165e5c31af7Sopenharmony_ci										  params.iterCountType == ITERCOUNTTYPE_STATIC	? de::toString(params.maxLoopIterCount)			: "<invalid>";
166e5c31af7Sopenharmony_ci		const char* const	body		= "color = cos(sin(color*1.25)*0.8);";
167e5c31af7Sopenharmony_ci		std::ostringstream&	op			= isVertCase ? vert : frag;
168e5c31af7Sopenharmony_ci
169e5c31af7Sopenharmony_ci		op << "	mediump vec4 color = " << (isVertCase ? "a_position.xyxy" : "gl_FragCoord") << ";\n";
170e5c31af7Sopenharmony_ci
171e5c31af7Sopenharmony_ci		if (params.loopType == LOOPTYPE_FOR)
172e5c31af7Sopenharmony_ci		{
173e5c31af7Sopenharmony_ci			op << "	for (highp int i = 0; i < " << iterCount << " || " << iterCount << " < 0; ++i)\n"
174e5c31af7Sopenharmony_ci			   << "		" << body << "\n";
175e5c31af7Sopenharmony_ci		}
176e5c31af7Sopenharmony_ci		else if (params.loopType == LOOPTYPE_WHILE)
177e5c31af7Sopenharmony_ci		{
178e5c31af7Sopenharmony_ci			op << "	highp int i = 0;\n"
179e5c31af7Sopenharmony_ci			   << "	while (i < " << iterCount << " || " << iterCount << " < 0) {\n"
180e5c31af7Sopenharmony_ci			   << "		i += 1;\n"
181e5c31af7Sopenharmony_ci			   << "		" << body << "\n"
182e5c31af7Sopenharmony_ci			   << "	}\n";
183e5c31af7Sopenharmony_ci		}
184e5c31af7Sopenharmony_ci		else
185e5c31af7Sopenharmony_ci		{
186e5c31af7Sopenharmony_ci			DE_ASSERT(params.loopType == LOOPTYPE_DO_WHILE);
187e5c31af7Sopenharmony_ci			op << "	highp int i = 0;\n"
188e5c31af7Sopenharmony_ci			   << "	do {\n"
189e5c31af7Sopenharmony_ci			   << "		i += 1;\n"
190e5c31af7Sopenharmony_ci			   << "		" << body << "\n"
191e5c31af7Sopenharmony_ci			   << "	} while (i <= " << iterCount << " || " << iterCount << " < 0);\n";
192e5c31af7Sopenharmony_ci		}
193e5c31af7Sopenharmony_ci	}
194e5c31af7Sopenharmony_ci
195e5c31af7Sopenharmony_ci	if (isVertCase)
196e5c31af7Sopenharmony_ci	{
197e5c31af7Sopenharmony_ci		vert << "	v_color = color;\n";
198e5c31af7Sopenharmony_ci		frag << "	o_color = v_color;\n";
199e5c31af7Sopenharmony_ci	}
200e5c31af7Sopenharmony_ci	else
201e5c31af7Sopenharmony_ci		frag << "	o_color = color;\n";
202e5c31af7Sopenharmony_ci
203e5c31af7Sopenharmony_ci	vert << "}\n";
204e5c31af7Sopenharmony_ci	frag << "}\n";
205e5c31af7Sopenharmony_ci
206e5c31af7Sopenharmony_ci	return glu::ProgramSources() << glu::VertexSource(vert.str()) << glu::FragmentSource(frag.str());
207e5c31af7Sopenharmony_ci}
208e5c31af7Sopenharmony_ci
209e5c31af7Sopenharmony_civoid LongRunningShaderCase::init (void)
210e5c31af7Sopenharmony_ci{
211e5c31af7Sopenharmony_ci	DE_ASSERT(!m_program);
212e5c31af7Sopenharmony_ci	m_program = new glu::ShaderProgram(m_context.getRenderContext(), genSources(*m_params));
213e5c31af7Sopenharmony_ci
214e5c31af7Sopenharmony_ci	m_testCtx.getLog() << *m_program;
215e5c31af7Sopenharmony_ci
216e5c31af7Sopenharmony_ci	if (!m_program->isOk())
217e5c31af7Sopenharmony_ci	{
218e5c31af7Sopenharmony_ci		deinit();
219e5c31af7Sopenharmony_ci		TCU_FAIL("Failed to compile shader program");
220e5c31af7Sopenharmony_ci	}
221e5c31af7Sopenharmony_ci
222e5c31af7Sopenharmony_ci	m_caseIterNdx = 0;
223e5c31af7Sopenharmony_ci
224e5c31af7Sopenharmony_ci	if (m_params->iterCountType != ITERCOUNTTYPE_STATIC)
225e5c31af7Sopenharmony_ci	{
226e5c31af7Sopenharmony_ci		m_testCtx.getLog() << TestLog::Message << "Loop iteration counts in range: [" << m_params->minLoopIterCount
227e5c31af7Sopenharmony_ci											   << ", " << m_params->maxLoopIterCount << "]"
228e5c31af7Sopenharmony_ci						   << TestLog::EndMessage;
229e5c31af7Sopenharmony_ci	}
230e5c31af7Sopenharmony_ci
231e5c31af7Sopenharmony_ci	m_testCtx.getLog() << TestLog::Message << "Number of vertices and fragments: " << m_params->numInvocations << TestLog::EndMessage;
232e5c31af7Sopenharmony_ci
233e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); // Test will pass or timeout, unless driver/device crashes.
234e5c31af7Sopenharmony_ci}
235e5c31af7Sopenharmony_ci
236e5c31af7Sopenharmony_civoid LongRunningShaderCase::deinit (void)
237e5c31af7Sopenharmony_ci{
238e5c31af7Sopenharmony_ci	delete m_program;
239e5c31af7Sopenharmony_ci	m_program = DE_NULL;
240e5c31af7Sopenharmony_ci}
241e5c31af7Sopenharmony_ci
242e5c31af7Sopenharmony_civoid genPositions (const tcu::RenderTarget& renderTarget, int numPoints, Vec2* positions)
243e5c31af7Sopenharmony_ci{
244e5c31af7Sopenharmony_ci	const int	width		= renderTarget.getWidth();
245e5c31af7Sopenharmony_ci	const int	height		= renderTarget.getHeight();
246e5c31af7Sopenharmony_ci
247e5c31af7Sopenharmony_ci	if (width*height < numPoints)
248e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("Too small viewport to fit all test points");
249e5c31af7Sopenharmony_ci
250e5c31af7Sopenharmony_ci	for (int pointNdx = 0; pointNdx < numPoints; pointNdx++)
251e5c31af7Sopenharmony_ci	{
252e5c31af7Sopenharmony_ci		const int		xi		= pointNdx % width;
253e5c31af7Sopenharmony_ci		const int		yi		= pointNdx / height;
254e5c31af7Sopenharmony_ci		const float		xf		= 2.0f * ((float(xi) + 0.5f) / float(width)) - 1.0f;
255e5c31af7Sopenharmony_ci		const float		yf		= 2.0f * ((float(yi) + 0.5f) / float(height)) - 1.0f;
256e5c31af7Sopenharmony_ci
257e5c31af7Sopenharmony_ci		positions[pointNdx] = Vec2(xf, yf);
258e5c31af7Sopenharmony_ci	}
259e5c31af7Sopenharmony_ci}
260e5c31af7Sopenharmony_ci
261e5c31af7Sopenharmony_cideUint32 LongRunningShaderCase::getSeed (const Params& params)
262e5c31af7Sopenharmony_ci{
263e5c31af7Sopenharmony_ci	const deUint32	seed	= deStringHash(params.name)
264e5c31af7Sopenharmony_ci							^ deInt32Hash(params.shaderType)
265e5c31af7Sopenharmony_ci							^ deInt32Hash(params.loopType)
266e5c31af7Sopenharmony_ci							^ deInt32Hash(params.iterCountType)
267e5c31af7Sopenharmony_ci							^ deInt32Hash(params.minLoopIterCount)
268e5c31af7Sopenharmony_ci							^ deInt32Hash(params.maxLoopIterCount)
269e5c31af7Sopenharmony_ci							^ deInt32Hash(params.numInvocations);
270e5c31af7Sopenharmony_ci	return seed;
271e5c31af7Sopenharmony_ci}
272e5c31af7Sopenharmony_ci
273e5c31af7Sopenharmony_ciLongRunningShaderCase::IterateResult LongRunningShaderCase::iterate (void)
274e5c31af7Sopenharmony_ci{
275e5c31af7Sopenharmony_ci	const glw::Functions&			gl				= m_context.getRenderContext().getFunctions();
276e5c31af7Sopenharmony_ci	de::Random						rnd				(getSeed(*m_params));
277e5c31af7Sopenharmony_ci	vector<Vec2>					positions		(m_params->numInvocations);
278e5c31af7Sopenharmony_ci	vector<int>						iterCounts		(m_params->iterCountType == ITERCOUNTTYPE_DYNAMIC ? m_params->numInvocations : 1);
279e5c31af7Sopenharmony_ci	vector<glu::VertexArrayBinding>	vertexArrays;
280e5c31af7Sopenharmony_ci
281e5c31af7Sopenharmony_ci	vertexArrays.push_back(glu::va::Float("a_position", 2, (int)positions.size(), 0, positions[0].getPtr()));
282e5c31af7Sopenharmony_ci	if (m_params->iterCountType == ITERCOUNTTYPE_DYNAMIC)
283e5c31af7Sopenharmony_ci		vertexArrays.push_back(glu::va::Int32("a_iterCount", 1, (int)iterCounts.size(), 0, &iterCounts[0]));
284e5c31af7Sopenharmony_ci
285e5c31af7Sopenharmony_ci	genPositions(m_context.getRenderTarget(), (int)positions.size(), &positions[0]);
286e5c31af7Sopenharmony_ci
287e5c31af7Sopenharmony_ci	for (vector<int>::iterator i = iterCounts.begin(); i != iterCounts.end(); ++i)
288e5c31af7Sopenharmony_ci		*i = rnd.getInt(m_params->minLoopIterCount, m_params->maxLoopIterCount);
289e5c31af7Sopenharmony_ci
290e5c31af7Sopenharmony_ci	gl.useProgram(m_program->getProgram());
291e5c31af7Sopenharmony_ci
292e5c31af7Sopenharmony_ci	if (m_params->iterCountType == ITERCOUNTTYPE_UNIFORM)
293e5c31af7Sopenharmony_ci		gl.uniform1i(gl.getUniformLocation(m_program->getProgram(), "u_iterCount"), iterCounts[0]);
294e5c31af7Sopenharmony_ci
295e5c31af7Sopenharmony_ci	glu::draw(m_context.getRenderContext(), m_program->getProgram(),
296e5c31af7Sopenharmony_ci			  (int)vertexArrays.size(), &vertexArrays[0],
297e5c31af7Sopenharmony_ci			  glu::pr::Points(m_params->numInvocations));
298e5c31af7Sopenharmony_ci
299e5c31af7Sopenharmony_ci	m_caseIterNdx += 1;
300e5c31af7Sopenharmony_ci	return (m_caseIterNdx < m_numCaseIters) ? CONTINUE : STOP;
301e5c31af7Sopenharmony_ci}
302e5c31af7Sopenharmony_ci
303e5c31af7Sopenharmony_ci} // anonymous
304e5c31af7Sopenharmony_ci
305e5c31af7Sopenharmony_ciLongRunningShaderTests::LongRunningShaderTests (Context& context)
306e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "long_running_shaders",	"Long-running shader stress tests")
307e5c31af7Sopenharmony_ci{
308e5c31af7Sopenharmony_ci}
309e5c31af7Sopenharmony_ci
310e5c31af7Sopenharmony_ciLongRunningShaderTests::~LongRunningShaderTests (void)
311e5c31af7Sopenharmony_ci{
312e5c31af7Sopenharmony_ci}
313e5c31af7Sopenharmony_ci
314e5c31af7Sopenharmony_civoid LongRunningShaderTests::init (void)
315e5c31af7Sopenharmony_ci{
316e5c31af7Sopenharmony_ci	const int	numInvocations	= 4096;
317e5c31af7Sopenharmony_ci	const int	shortLoopMin	= 5;
318e5c31af7Sopenharmony_ci	const int	shortLoopMax	= 10;
319e5c31af7Sopenharmony_ci	const int	mediumLoopMin	= 10000;
320e5c31af7Sopenharmony_ci	const int	mediumLoopMax	= 50000;
321e5c31af7Sopenharmony_ci	const int	longLoopMin		= 100000;
322e5c31af7Sopenharmony_ci	const int	longLoopMax		= 500000;
323e5c31af7Sopenharmony_ci
324e5c31af7Sopenharmony_ci	static const LongRunningShaderCase::Params s_cases[] =
325e5c31af7Sopenharmony_ci	{
326e5c31af7Sopenharmony_ci		{ "short_for_vertex",					"",	glu::SHADERTYPE_VERTEX,		LOOPTYPE_FOR,		ITERCOUNTTYPE_DYNAMIC,	numInvocations,	shortLoopMin,	shortLoopMax	},
327e5c31af7Sopenharmony_ci		{ "short_for_fragment",					"",	glu::SHADERTYPE_FRAGMENT,	LOOPTYPE_FOR,		ITERCOUNTTYPE_DYNAMIC,	numInvocations,	shortLoopMin,	shortLoopMax	},
328e5c31af7Sopenharmony_ci		{ "short_while_vertex",					"",	glu::SHADERTYPE_VERTEX,		LOOPTYPE_WHILE,		ITERCOUNTTYPE_DYNAMIC,	numInvocations,	shortLoopMin,	shortLoopMax	},
329e5c31af7Sopenharmony_ci		{ "short_while_fragment",				"",	glu::SHADERTYPE_FRAGMENT,	LOOPTYPE_WHILE,		ITERCOUNTTYPE_DYNAMIC,	numInvocations,	shortLoopMin,	shortLoopMax	},
330e5c31af7Sopenharmony_ci		{ "short_do_while_vertex",				"",	glu::SHADERTYPE_VERTEX,		LOOPTYPE_DO_WHILE,	ITERCOUNTTYPE_DYNAMIC,	numInvocations,	shortLoopMin,	shortLoopMax	},
331e5c31af7Sopenharmony_ci		{ "short_do_while_fragment",			"",	glu::SHADERTYPE_FRAGMENT,	LOOPTYPE_DO_WHILE,	ITERCOUNTTYPE_DYNAMIC,	numInvocations,	shortLoopMin,	shortLoopMax	},
332e5c31af7Sopenharmony_ci
333e5c31af7Sopenharmony_ci		{ "medium_static_for_vertex",			"",	glu::SHADERTYPE_VERTEX,		LOOPTYPE_FOR,		ITERCOUNTTYPE_STATIC,	numInvocations,	mediumLoopMin,	mediumLoopMax	},
334e5c31af7Sopenharmony_ci		{ "medium_static_while_fragment",		"",	glu::SHADERTYPE_FRAGMENT,	LOOPTYPE_WHILE,		ITERCOUNTTYPE_STATIC,	numInvocations,	mediumLoopMin,	mediumLoopMax	},
335e5c31af7Sopenharmony_ci		{ "medium_uniform_do_while_vertex",		"",	glu::SHADERTYPE_VERTEX,		LOOPTYPE_DO_WHILE,	ITERCOUNTTYPE_UNIFORM,	numInvocations,	mediumLoopMin,	mediumLoopMax	},
336e5c31af7Sopenharmony_ci		{ "medium_uniform_for_fragment",		"",	glu::SHADERTYPE_FRAGMENT,	LOOPTYPE_FOR,		ITERCOUNTTYPE_UNIFORM,	numInvocations,	mediumLoopMin,	mediumLoopMax	},
337e5c31af7Sopenharmony_ci
338e5c31af7Sopenharmony_ci		{ "medium_dynamic_for_vertex",			"",	glu::SHADERTYPE_VERTEX,		LOOPTYPE_FOR,		ITERCOUNTTYPE_DYNAMIC,	numInvocations,	mediumLoopMin,	mediumLoopMax	},
339e5c31af7Sopenharmony_ci		{ "medium_dynamic_for_fragment",		"",	glu::SHADERTYPE_FRAGMENT,	LOOPTYPE_FOR,		ITERCOUNTTYPE_DYNAMIC,	numInvocations,	mediumLoopMin,	mediumLoopMax	},
340e5c31af7Sopenharmony_ci		{ "medium_dynamic_while_vertex",		"",	glu::SHADERTYPE_VERTEX,		LOOPTYPE_WHILE,		ITERCOUNTTYPE_DYNAMIC,	numInvocations,	mediumLoopMin,	mediumLoopMax	},
341e5c31af7Sopenharmony_ci		{ "medium_dynamic_while_fragment",		"",	glu::SHADERTYPE_FRAGMENT,	LOOPTYPE_WHILE,		ITERCOUNTTYPE_DYNAMIC,	numInvocations,	mediumLoopMin,	mediumLoopMax	},
342e5c31af7Sopenharmony_ci		{ "medium_dynamic_do_while_vertex",		"",	glu::SHADERTYPE_VERTEX,		LOOPTYPE_DO_WHILE,	ITERCOUNTTYPE_DYNAMIC,	numInvocations,	mediumLoopMin,	mediumLoopMax	},
343e5c31af7Sopenharmony_ci		{ "medium_dynamic_do_while_fragment",	"",	glu::SHADERTYPE_FRAGMENT,	LOOPTYPE_DO_WHILE,	ITERCOUNTTYPE_DYNAMIC,	numInvocations,	mediumLoopMin,	mediumLoopMax	},
344e5c31af7Sopenharmony_ci
345e5c31af7Sopenharmony_ci		{ "long_static_while_vertex",			"",	glu::SHADERTYPE_VERTEX,		LOOPTYPE_WHILE,		ITERCOUNTTYPE_STATIC,	numInvocations,	longLoopMin,	longLoopMax		},
346e5c31af7Sopenharmony_ci		{ "long_static_do_while_fragment",		"",	glu::SHADERTYPE_FRAGMENT,	LOOPTYPE_DO_WHILE,	ITERCOUNTTYPE_STATIC,	numInvocations,	longLoopMin,	longLoopMax		},
347e5c31af7Sopenharmony_ci		{ "long_uniform_for_vertex",			"",	glu::SHADERTYPE_VERTEX,		LOOPTYPE_FOR,		ITERCOUNTTYPE_UNIFORM,	numInvocations,	longLoopMin,	longLoopMax		},
348e5c31af7Sopenharmony_ci		{ "long_uniform_do_while_fragment",		"",	glu::SHADERTYPE_FRAGMENT,	LOOPTYPE_DO_WHILE,	ITERCOUNTTYPE_UNIFORM,	numInvocations,	longLoopMin,	longLoopMax		},
349e5c31af7Sopenharmony_ci
350e5c31af7Sopenharmony_ci		{ "long_dynamic_for_vertex",			"",	glu::SHADERTYPE_VERTEX,		LOOPTYPE_FOR,		ITERCOUNTTYPE_DYNAMIC,	numInvocations,	longLoopMin,	longLoopMax		},
351e5c31af7Sopenharmony_ci		{ "long_dynamic_for_fragment",			"",	glu::SHADERTYPE_FRAGMENT,	LOOPTYPE_FOR,		ITERCOUNTTYPE_DYNAMIC,	numInvocations,	longLoopMin,	longLoopMax		},
352e5c31af7Sopenharmony_ci		{ "long_dynamic_while_vertex",			"",	glu::SHADERTYPE_VERTEX,		LOOPTYPE_WHILE,		ITERCOUNTTYPE_DYNAMIC,	numInvocations,	longLoopMin,	longLoopMax		},
353e5c31af7Sopenharmony_ci		{ "long_dynamic_while_fragment",		"",	glu::SHADERTYPE_FRAGMENT,	LOOPTYPE_WHILE,		ITERCOUNTTYPE_DYNAMIC,	numInvocations,	longLoopMin,	longLoopMax		},
354e5c31af7Sopenharmony_ci		{ "long_dynamic_do_while_vertex",		"",	glu::SHADERTYPE_VERTEX,		LOOPTYPE_DO_WHILE,	ITERCOUNTTYPE_DYNAMIC,	numInvocations,	longLoopMin,	longLoopMax		},
355e5c31af7Sopenharmony_ci		{ "long_dynamic_do_while_fragment",		"",	glu::SHADERTYPE_FRAGMENT,	LOOPTYPE_DO_WHILE,	ITERCOUNTTYPE_DYNAMIC,	numInvocations,	longLoopMin,	longLoopMax		},
356e5c31af7Sopenharmony_ci
357e5c31af7Sopenharmony_ci		{ "infinite_for_vertex",				"",	glu::SHADERTYPE_VERTEX,		LOOPTYPE_FOR,		ITERCOUNTTYPE_DYNAMIC,	numInvocations,	-1,				-1				},
358e5c31af7Sopenharmony_ci		{ "infinite_for_fragment",				"",	glu::SHADERTYPE_FRAGMENT,	LOOPTYPE_FOR,		ITERCOUNTTYPE_DYNAMIC,	numInvocations,	-1,				-1				},
359e5c31af7Sopenharmony_ci		{ "infinite_while_vertex",				"",	glu::SHADERTYPE_VERTEX,		LOOPTYPE_WHILE,		ITERCOUNTTYPE_DYNAMIC,	numInvocations,	-1,				-1				},
360e5c31af7Sopenharmony_ci		{ "infinite_while_fragment",			"",	glu::SHADERTYPE_FRAGMENT,	LOOPTYPE_WHILE,		ITERCOUNTTYPE_DYNAMIC,	numInvocations,	-1,				-1				},
361e5c31af7Sopenharmony_ci		{ "infinite_do_while_vertex",			"",	glu::SHADERTYPE_VERTEX,		LOOPTYPE_DO_WHILE,	ITERCOUNTTYPE_DYNAMIC,	numInvocations,	-1,				-1				},
362e5c31af7Sopenharmony_ci		{ "infinite_do_while_fragment",			"",	glu::SHADERTYPE_FRAGMENT,	LOOPTYPE_DO_WHILE,	ITERCOUNTTYPE_DYNAMIC,	numInvocations,	-1,				-1				},
363e5c31af7Sopenharmony_ci	};
364e5c31af7Sopenharmony_ci
365e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_cases); ndx++)
366e5c31af7Sopenharmony_ci		addChild(new LongRunningShaderCase(m_context, &s_cases[ndx]));
367e5c31af7Sopenharmony_ci}
368e5c31af7Sopenharmony_ci
369e5c31af7Sopenharmony_ci} // Stress
370e5c31af7Sopenharmony_ci} // gles3
371e5c31af7Sopenharmony_ci} // deqp
372