1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite
3e5c31af7Sopenharmony_ci * -----------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright (c) 2016 Google Inc.
6e5c31af7Sopenharmony_ci * Copyright (c) 2016 The Khronos Group Inc.
7e5c31af7Sopenharmony_ci *
8e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
9e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
10e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
11e5c31af7Sopenharmony_ci *
12e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
13e5c31af7Sopenharmony_ci *
14e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
15e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
16e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
18e5c31af7Sopenharmony_ci * limitations under the License.
19e5c31af7Sopenharmony_ci *
20e5c31af7Sopenharmony_ci */ /*!
21e5c31af7Sopenharmony_ci * \file
22e5c31af7Sopenharmony_ci * \brief CTS runner.
23e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/
24e5c31af7Sopenharmony_ci
25e5c31af7Sopenharmony_ci#include "glcTestRunner.hpp"
26e5c31af7Sopenharmony_ci#include "deFilePath.hpp"
27e5c31af7Sopenharmony_ci#include "deStringUtil.hpp"
28e5c31af7Sopenharmony_ci#include "deUniquePtr.hpp"
29e5c31af7Sopenharmony_ci#include "glcConfigList.hpp"
30e5c31af7Sopenharmony_ci#include "qpXmlWriter.h"
31e5c31af7Sopenharmony_ci#include "tcuApp.hpp"
32e5c31af7Sopenharmony_ci#include "tcuCommandLine.hpp"
33e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp"
34e5c31af7Sopenharmony_ci#include "tcuTestSessionExecutor.hpp"
35e5c31af7Sopenharmony_ci
36e5c31af7Sopenharmony_ci#include <iterator>
37e5c31af7Sopenharmony_ci
38e5c31af7Sopenharmony_cinamespace glcts
39e5c31af7Sopenharmony_ci{
40e5c31af7Sopenharmony_ci
41e5c31af7Sopenharmony_ciusing std::vector;
42e5c31af7Sopenharmony_ciusing std::string;
43e5c31af7Sopenharmony_ci
44e5c31af7Sopenharmony_ci// RunSession
45e5c31af7Sopenharmony_ci
46e5c31af7Sopenharmony_ciclass RunSession
47e5c31af7Sopenharmony_ci{
48e5c31af7Sopenharmony_cipublic:
49e5c31af7Sopenharmony_ci	RunSession(tcu::Platform& platform, tcu::Archive& archive, const int numArgs, const char* const* args)
50e5c31af7Sopenharmony_ci		: m_cmdLine(numArgs, args)
51e5c31af7Sopenharmony_ci		, m_log(m_cmdLine.getLogFileName(), m_cmdLine.getLogFlags())
52e5c31af7Sopenharmony_ci		, m_app(platform, archive, m_log, m_cmdLine)
53e5c31af7Sopenharmony_ci	{
54e5c31af7Sopenharmony_ci		const std::string sessionInfo = "#sessionInfo commandLineParameters \"";
55e5c31af7Sopenharmony_ci		m_log.writeSessionInfo(sessionInfo + m_cmdLine.getInitialCmdLine() + "\"\n");
56e5c31af7Sopenharmony_ci	}
57e5c31af7Sopenharmony_ci
58e5c31af7Sopenharmony_ci	inline bool iterate(void)
59e5c31af7Sopenharmony_ci	{
60e5c31af7Sopenharmony_ci		return m_app.iterate();
61e5c31af7Sopenharmony_ci	}
62e5c31af7Sopenharmony_ci
63e5c31af7Sopenharmony_ci	inline const tcu::TestRunStatus& getResult(void) const
64e5c31af7Sopenharmony_ci	{
65e5c31af7Sopenharmony_ci		return m_app.getResult();
66e5c31af7Sopenharmony_ci	}
67e5c31af7Sopenharmony_ci
68e5c31af7Sopenharmony_ciprivate:
69e5c31af7Sopenharmony_ci	tcu::CommandLine m_cmdLine;
70e5c31af7Sopenharmony_ci	tcu::TestLog	 m_log;
71e5c31af7Sopenharmony_ci	tcu::App		 m_app;
72e5c31af7Sopenharmony_ci};
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_cistatic void appendConfigArgs(const Config& config, std::vector<std::string>& args, const char* fboConfig)
75e5c31af7Sopenharmony_ci{
76e5c31af7Sopenharmony_ci	if (fboConfig != NULL)
77e5c31af7Sopenharmony_ci	{
78e5c31af7Sopenharmony_ci		args.push_back(string("--deqp-gl-config-name=") + fboConfig);
79e5c31af7Sopenharmony_ci		args.push_back("--deqp-surface-type=fbo");
80e5c31af7Sopenharmony_ci	}
81e5c31af7Sopenharmony_ci
82e5c31af7Sopenharmony_ci	if (config.type != CONFIGTYPE_DEFAULT)
83e5c31af7Sopenharmony_ci	{
84e5c31af7Sopenharmony_ci		// \todo [2013-05-06 pyry] Test all surface types for some configs?
85e5c31af7Sopenharmony_ci		if (fboConfig == NULL)
86e5c31af7Sopenharmony_ci		{
87e5c31af7Sopenharmony_ci			if (config.surfaceTypes & SURFACETYPE_WINDOW)
88e5c31af7Sopenharmony_ci				args.push_back("--deqp-surface-type=window");
89e5c31af7Sopenharmony_ci			else if (config.surfaceTypes & SURFACETYPE_PBUFFER)
90e5c31af7Sopenharmony_ci				args.push_back("--deqp-surface-type=pbuffer");
91e5c31af7Sopenharmony_ci			else if (config.surfaceTypes & SURFACETYPE_PIXMAP)
92e5c31af7Sopenharmony_ci				args.push_back("--deqp-surface-type=pixmap");
93e5c31af7Sopenharmony_ci		}
94e5c31af7Sopenharmony_ci
95e5c31af7Sopenharmony_ci		args.push_back(string("--deqp-gl-config-id=") + de::toString(config.id));
96e5c31af7Sopenharmony_ci
97e5c31af7Sopenharmony_ci		if (config.type == CONFIGTYPE_EGL)
98e5c31af7Sopenharmony_ci			args.push_back("--deqp-gl-context-type=egl");
99e5c31af7Sopenharmony_ci		else if (config.type == CONFIGTYPE_WGL)
100e5c31af7Sopenharmony_ci			args.push_back("--deqp-gl-context-type=wgl");
101e5c31af7Sopenharmony_ci	}
102e5c31af7Sopenharmony_ci}
103e5c31af7Sopenharmony_ci
104e5c31af7Sopenharmony_citypedef struct configInfo
105e5c31af7Sopenharmony_ci{
106e5c31af7Sopenharmony_ci	deInt32 redBits;
107e5c31af7Sopenharmony_ci	deInt32 greenBits;
108e5c31af7Sopenharmony_ci	deInt32 blueBits;
109e5c31af7Sopenharmony_ci	deInt32 alphaBits;
110e5c31af7Sopenharmony_ci	deInt32 depthBits;
111e5c31af7Sopenharmony_ci	deInt32 stencilBits;
112e5c31af7Sopenharmony_ci	deInt32 samples;
113e5c31af7Sopenharmony_ci} configInfo;
114e5c31af7Sopenharmony_ci
115e5c31af7Sopenharmony_cistatic configInfo parseConfigBitsFromName(const char* configName)
116e5c31af7Sopenharmony_ci{
117e5c31af7Sopenharmony_ci	configInfo cfgInfo;
118e5c31af7Sopenharmony_ci	static const struct
119e5c31af7Sopenharmony_ci	{
120e5c31af7Sopenharmony_ci		const char* name;
121e5c31af7Sopenharmony_ci		int			redBits;
122e5c31af7Sopenharmony_ci		int			greenBits;
123e5c31af7Sopenharmony_ci		int			blueBits;
124e5c31af7Sopenharmony_ci		int			alphaBits;
125e5c31af7Sopenharmony_ci	} colorCfgs[] = {
126e5c31af7Sopenharmony_ci		{ "rgba8888", 8, 8, 8, 8 }, { "rgb565", 5, 6, 5, 0 },
127e5c31af7Sopenharmony_ci	};
128e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorCfgs); ndx++)
129e5c31af7Sopenharmony_ci	{
130e5c31af7Sopenharmony_ci		if (!strncmp(configName, colorCfgs[ndx].name, strlen(colorCfgs[ndx].name)))
131e5c31af7Sopenharmony_ci		{
132e5c31af7Sopenharmony_ci			cfgInfo.redBits   = colorCfgs[ndx].redBits;
133e5c31af7Sopenharmony_ci			cfgInfo.greenBits = colorCfgs[ndx].greenBits;
134e5c31af7Sopenharmony_ci			cfgInfo.blueBits  = colorCfgs[ndx].blueBits;
135e5c31af7Sopenharmony_ci			cfgInfo.alphaBits = colorCfgs[ndx].alphaBits;
136e5c31af7Sopenharmony_ci
137e5c31af7Sopenharmony_ci			configName += strlen(colorCfgs[ndx].name);
138e5c31af7Sopenharmony_ci			break;
139e5c31af7Sopenharmony_ci		}
140e5c31af7Sopenharmony_ci	}
141e5c31af7Sopenharmony_ci
142e5c31af7Sopenharmony_ci	static const struct
143e5c31af7Sopenharmony_ci	{
144e5c31af7Sopenharmony_ci		const char* name;
145e5c31af7Sopenharmony_ci		int			depthBits;
146e5c31af7Sopenharmony_ci	} depthCfgs[] = {
147e5c31af7Sopenharmony_ci		{ "d0", 0 }, { "d24", 24 },
148e5c31af7Sopenharmony_ci	};
149e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthCfgs); ndx++)
150e5c31af7Sopenharmony_ci	{
151e5c31af7Sopenharmony_ci		if (!strncmp(configName, depthCfgs[ndx].name, strlen(depthCfgs[ndx].name)))
152e5c31af7Sopenharmony_ci		{
153e5c31af7Sopenharmony_ci			cfgInfo.depthBits = depthCfgs[ndx].depthBits;
154e5c31af7Sopenharmony_ci
155e5c31af7Sopenharmony_ci			configName += strlen(depthCfgs[ndx].name);
156e5c31af7Sopenharmony_ci			break;
157e5c31af7Sopenharmony_ci		}
158e5c31af7Sopenharmony_ci	}
159e5c31af7Sopenharmony_ci
160e5c31af7Sopenharmony_ci	static const struct
161e5c31af7Sopenharmony_ci	{
162e5c31af7Sopenharmony_ci		const char* name;
163e5c31af7Sopenharmony_ci		int			stencilBits;
164e5c31af7Sopenharmony_ci	} stencilCfgs[] = {
165e5c31af7Sopenharmony_ci		{ "s0", 0 }, { "s8", 8 },
166e5c31af7Sopenharmony_ci	};
167e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stencilCfgs); ndx++)
168e5c31af7Sopenharmony_ci	{
169e5c31af7Sopenharmony_ci		if (!strncmp(configName, stencilCfgs[ndx].name, strlen(stencilCfgs[ndx].name)))
170e5c31af7Sopenharmony_ci		{
171e5c31af7Sopenharmony_ci			cfgInfo.stencilBits = stencilCfgs[ndx].stencilBits;
172e5c31af7Sopenharmony_ci
173e5c31af7Sopenharmony_ci			configName += strlen(stencilCfgs[ndx].name);
174e5c31af7Sopenharmony_ci			break;
175e5c31af7Sopenharmony_ci		}
176e5c31af7Sopenharmony_ci	}
177e5c31af7Sopenharmony_ci
178e5c31af7Sopenharmony_ci	static const struct
179e5c31af7Sopenharmony_ci	{
180e5c31af7Sopenharmony_ci		const char* name;
181e5c31af7Sopenharmony_ci		int			samples;
182e5c31af7Sopenharmony_ci	} multiSampleCfgs[] = {
183e5c31af7Sopenharmony_ci		{ "ms0", 0 }, { "ms4", 4 },
184e5c31af7Sopenharmony_ci	};
185e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(multiSampleCfgs); ndx++)
186e5c31af7Sopenharmony_ci	{
187e5c31af7Sopenharmony_ci		if (!strncmp(configName, multiSampleCfgs[ndx].name, strlen(multiSampleCfgs[ndx].name)))
188e5c31af7Sopenharmony_ci		{
189e5c31af7Sopenharmony_ci			cfgInfo.samples = multiSampleCfgs[ndx].samples;
190e5c31af7Sopenharmony_ci
191e5c31af7Sopenharmony_ci			configName += strlen(multiSampleCfgs[ndx].name);
192e5c31af7Sopenharmony_ci			break;
193e5c31af7Sopenharmony_ci		}
194e5c31af7Sopenharmony_ci	}
195e5c31af7Sopenharmony_ci
196e5c31af7Sopenharmony_ci	return cfgInfo;
197e5c31af7Sopenharmony_ci}
198e5c31af7Sopenharmony_ci
199e5c31af7Sopenharmony_cistatic const char* getApiName(glu::ApiType apiType)
200e5c31af7Sopenharmony_ci{
201e5c31af7Sopenharmony_ci	if (apiType == glu::ApiType::es(2, 0))
202e5c31af7Sopenharmony_ci		return "gles2";
203e5c31af7Sopenharmony_ci	else if (apiType == glu::ApiType::es(3, 0))
204e5c31af7Sopenharmony_ci		return "gles3";
205e5c31af7Sopenharmony_ci	else if (apiType == glu::ApiType::es(3, 1))
206e5c31af7Sopenharmony_ci		return "gles31";
207e5c31af7Sopenharmony_ci	else if (apiType == glu::ApiType::es(3, 2))
208e5c31af7Sopenharmony_ci		return "gles32";
209e5c31af7Sopenharmony_ci	else if (apiType == glu::ApiType::core(3, 0))
210e5c31af7Sopenharmony_ci		return "gl30";
211e5c31af7Sopenharmony_ci	else if (apiType == glu::ApiType::core(3, 1))
212e5c31af7Sopenharmony_ci		return "gl31";
213e5c31af7Sopenharmony_ci	else if (apiType == glu::ApiType::core(3, 2))
214e5c31af7Sopenharmony_ci		return "gl32";
215e5c31af7Sopenharmony_ci	else if (apiType == glu::ApiType::core(3, 3))
216e5c31af7Sopenharmony_ci		return "gl33";
217e5c31af7Sopenharmony_ci	else if (apiType == glu::ApiType::core(4, 0))
218e5c31af7Sopenharmony_ci		return "gl40";
219e5c31af7Sopenharmony_ci	else if (apiType == glu::ApiType::core(4, 1))
220e5c31af7Sopenharmony_ci		return "gl41";
221e5c31af7Sopenharmony_ci	else if (apiType == glu::ApiType::core(4, 2))
222e5c31af7Sopenharmony_ci		return "gl42";
223e5c31af7Sopenharmony_ci	else if (apiType == glu::ApiType::core(4, 3))
224e5c31af7Sopenharmony_ci		return "gl43";
225e5c31af7Sopenharmony_ci	else if (apiType == glu::ApiType::core(4, 4))
226e5c31af7Sopenharmony_ci		return "gl44";
227e5c31af7Sopenharmony_ci	else if (apiType == glu::ApiType::core(4, 5))
228e5c31af7Sopenharmony_ci		return "gl45";
229e5c31af7Sopenharmony_ci	else if (apiType == glu::ApiType::core(4, 6))
230e5c31af7Sopenharmony_ci		return "gl46";
231e5c31af7Sopenharmony_ci	else
232e5c31af7Sopenharmony_ci		throw std::runtime_error("Unknown context type");
233e5c31af7Sopenharmony_ci}
234e5c31af7Sopenharmony_ci
235e5c31af7Sopenharmony_cistatic const string getCaseListFileOption(const char* mustpassDir, const char* apiName, const char* mustpassName)
236e5c31af7Sopenharmony_ci{
237e5c31af7Sopenharmony_ci#if DE_OS == DE_OS_ANDROID
238e5c31af7Sopenharmony_ci	const string case_list_option = "--deqp-caselist-resource=";
239e5c31af7Sopenharmony_ci#else
240e5c31af7Sopenharmony_ci	const string case_list_option = "--deqp-caselist-file=";
241e5c31af7Sopenharmony_ci#endif
242e5c31af7Sopenharmony_ci	return case_list_option + mustpassDir + apiName + "-" + mustpassName + ".txt";
243e5c31af7Sopenharmony_ci}
244e5c31af7Sopenharmony_ci
245e5c31af7Sopenharmony_cistatic const string getLogFileName(const char* apiName, const char* configName, const int iterId, const int runId,
246e5c31af7Sopenharmony_ci								   const int width, const int height, const int seed)
247e5c31af7Sopenharmony_ci{
248e5c31af7Sopenharmony_ci	string res = string("config-") + apiName + "-" + configName + "-cfg-" + de::toString(iterId) + "-run-" +
249e5c31af7Sopenharmony_ci				 de::toString(runId) + "-width-" + de::toString(width) + "-height-" + de::toString(height);
250e5c31af7Sopenharmony_ci	if (seed != -1)
251e5c31af7Sopenharmony_ci	{
252e5c31af7Sopenharmony_ci		res += "-seed-" + de::toString(seed);
253e5c31af7Sopenharmony_ci	}
254e5c31af7Sopenharmony_ci	res += ".qpa";
255e5c31af7Sopenharmony_ci
256e5c31af7Sopenharmony_ci	return res;
257e5c31af7Sopenharmony_ci}
258e5c31af7Sopenharmony_ci
259e5c31af7Sopenharmony_cistatic void getBaseOptions(std::vector<std::string>& args, const char* mustpassDir, const char* apiName,
260e5c31af7Sopenharmony_ci						   const char* configName, const char* screenRotation, int width, int height)
261e5c31af7Sopenharmony_ci{
262e5c31af7Sopenharmony_ci	args.push_back(getCaseListFileOption(mustpassDir, apiName, configName));
263e5c31af7Sopenharmony_ci	args.push_back(string("--deqp-screen-rotation=") + screenRotation);
264e5c31af7Sopenharmony_ci	args.push_back(string("--deqp-surface-width=") + de::toString(width));
265e5c31af7Sopenharmony_ci	args.push_back(string("--deqp-surface-height=") + de::toString(height));
266e5c31af7Sopenharmony_ci	args.push_back("--deqp-watchdog=disable");
267e5c31af7Sopenharmony_ci}
268e5c31af7Sopenharmony_ci
269e5c31af7Sopenharmony_cistatic bool isGLConfigCompatible(configInfo cfgInfo, const AOSPConfig& config)
270e5c31af7Sopenharmony_ci{
271e5c31af7Sopenharmony_ci	return cfgInfo.redBits == config.redBits && cfgInfo.greenBits == config.greenBits &&
272e5c31af7Sopenharmony_ci		   cfgInfo.blueBits == config.blueBits && cfgInfo.alphaBits == config.alphaBits &&
273e5c31af7Sopenharmony_ci		   cfgInfo.depthBits == config.depthBits && cfgInfo.stencilBits == config.stencilBits &&
274e5c31af7Sopenharmony_ci		   cfgInfo.samples == config.samples;
275e5c31af7Sopenharmony_ci}
276e5c31af7Sopenharmony_ci
277e5c31af7Sopenharmony_cistatic void getTestRunsForAOSPEGL(vector<TestRunParams>& runs, const ConfigList& configs)
278e5c31af7Sopenharmony_ci{
279e5c31af7Sopenharmony_ci#include "glcAospMustpassEgl.hpp"
280e5c31af7Sopenharmony_ci
281e5c31af7Sopenharmony_ci	for (int i = 0; i < DE_LENGTH_OF_ARRAY(aosp_mustpass_egl_first_cfg); ++i)
282e5c31af7Sopenharmony_ci	{
283e5c31af7Sopenharmony_ci		configInfo cfgInfo = parseConfigBitsFromName(aosp_mustpass_egl_first_cfg[i].glConfigName);
284e5c31af7Sopenharmony_ci
285e5c31af7Sopenharmony_ci		vector<AOSPConfig>::const_iterator cfgIter;
286e5c31af7Sopenharmony_ci		for (cfgIter = configs.aospConfigs.begin(); cfgIter != configs.aospConfigs.end(); ++cfgIter)
287e5c31af7Sopenharmony_ci		{
288e5c31af7Sopenharmony_ci			// find first compatible config
289e5c31af7Sopenharmony_ci			if ((*cfgIter).type == CONFIGTYPE_EGL && isGLConfigCompatible(cfgInfo, *cfgIter))
290e5c31af7Sopenharmony_ci			{
291e5c31af7Sopenharmony_ci				break;
292e5c31af7Sopenharmony_ci			}
293e5c31af7Sopenharmony_ci		}
294e5c31af7Sopenharmony_ci
295e5c31af7Sopenharmony_ci		if (cfgIter == configs.aospConfigs.end())
296e5c31af7Sopenharmony_ci		{
297e5c31af7Sopenharmony_ci			// No suitable configuration found. Skipping EGL tests
298e5c31af7Sopenharmony_ci			continue;
299e5c31af7Sopenharmony_ci		}
300e5c31af7Sopenharmony_ci
301e5c31af7Sopenharmony_ci		const char* apiName = "egl";
302e5c31af7Sopenharmony_ci
303e5c31af7Sopenharmony_ci		const int width   = aosp_mustpass_egl_first_cfg[i].surfaceWidth;
304e5c31af7Sopenharmony_ci		const int height  = aosp_mustpass_egl_first_cfg[i].surfaceHeight;
305e5c31af7Sopenharmony_ci
306e5c31af7Sopenharmony_ci		TestRunParams params;
307e5c31af7Sopenharmony_ci		params.logFilename =
308e5c31af7Sopenharmony_ci			getLogFileName(apiName, aosp_mustpass_egl_first_cfg[i].configName, 1, i, width, height, -1);
309e5c31af7Sopenharmony_ci		getBaseOptions(params.args, mustpassDir, apiName, aosp_mustpass_egl_first_cfg[i].configName,
310e5c31af7Sopenharmony_ci					   aosp_mustpass_egl_first_cfg[i].screenRotation, width, height);
311e5c31af7Sopenharmony_ci
312e5c31af7Sopenharmony_ci		params.args.push_back(string("--deqp-gl-config-name=") + string(aosp_mustpass_egl_first_cfg[i].glConfigName));
313e5c31af7Sopenharmony_ci
314e5c31af7Sopenharmony_ci		runs.push_back(params);
315e5c31af7Sopenharmony_ci	}
316e5c31af7Sopenharmony_ci}
317e5c31af7Sopenharmony_ci
318e5c31af7Sopenharmony_cistatic void getTestRunsForAOSPES(vector<TestRunParams>& runs, const ConfigList& configs, const glu::ApiType apiType)
319e5c31af7Sopenharmony_ci{
320e5c31af7Sopenharmony_ci#include "glcAospMustpassEs.hpp"
321e5c31af7Sopenharmony_ci
322e5c31af7Sopenharmony_ci	for (int i = 0; i < DE_LENGTH_OF_ARRAY(aosp_mustpass_es_first_cfg); ++i)
323e5c31af7Sopenharmony_ci	{
324e5c31af7Sopenharmony_ci		if (!glu::contextSupports(glu::ContextType(apiType), aosp_mustpass_es_first_cfg[i].apiType))
325e5c31af7Sopenharmony_ci			continue;
326e5c31af7Sopenharmony_ci
327e5c31af7Sopenharmony_ci		configInfo cfgInfo = parseConfigBitsFromName(aosp_mustpass_es_first_cfg[i].glConfigName);
328e5c31af7Sopenharmony_ci
329e5c31af7Sopenharmony_ci		vector<AOSPConfig>::const_iterator cfgIter;
330e5c31af7Sopenharmony_ci		for (cfgIter = configs.aospConfigs.begin(); cfgIter != configs.aospConfigs.end(); ++cfgIter)
331e5c31af7Sopenharmony_ci		{
332e5c31af7Sopenharmony_ci			// find first compatible config
333e5c31af7Sopenharmony_ci			if (isGLConfigCompatible(cfgInfo, *cfgIter))
334e5c31af7Sopenharmony_ci			{
335e5c31af7Sopenharmony_ci				break;
336e5c31af7Sopenharmony_ci			}
337e5c31af7Sopenharmony_ci		}
338e5c31af7Sopenharmony_ci
339e5c31af7Sopenharmony_ci		if (cfgIter == configs.aospConfigs.end())
340e5c31af7Sopenharmony_ci		{
341e5c31af7Sopenharmony_ci			TCU_FAIL(("No suitable configuration found for GL config " +
342e5c31af7Sopenharmony_ci					  de::toString(aosp_mustpass_es_first_cfg[i].glConfigName))
343e5c31af7Sopenharmony_ci						 .c_str());
344e5c31af7Sopenharmony_ci			return;
345e5c31af7Sopenharmony_ci		}
346e5c31af7Sopenharmony_ci
347e5c31af7Sopenharmony_ci		const char* apiName = getApiName(aosp_mustpass_es_first_cfg[i].apiType);
348e5c31af7Sopenharmony_ci
349e5c31af7Sopenharmony_ci		const int width   = aosp_mustpass_es_first_cfg[i].surfaceWidth;
350e5c31af7Sopenharmony_ci		const int height  = aosp_mustpass_es_first_cfg[i].surfaceHeight;
351e5c31af7Sopenharmony_ci
352e5c31af7Sopenharmony_ci		TestRunParams params;
353e5c31af7Sopenharmony_ci		params.logFilename = getLogFileName(apiName, aosp_mustpass_es_first_cfg[i].configName, 1, i, width, height, -1);
354e5c31af7Sopenharmony_ci		getBaseOptions(params.args, mustpassDir, apiName, aosp_mustpass_es_first_cfg[i].configName,
355e5c31af7Sopenharmony_ci					   aosp_mustpass_es_first_cfg[i].screenRotation, width, height);
356e5c31af7Sopenharmony_ci
357e5c31af7Sopenharmony_ci		params.args.push_back(string("--deqp-gl-config-name=") + string(aosp_mustpass_es_first_cfg[i].glConfigName));
358e5c31af7Sopenharmony_ci
359e5c31af7Sopenharmony_ci		//set surface type
360e5c31af7Sopenharmony_ci		if ((*cfgIter).surfaceTypes & SURFACETYPE_WINDOW)
361e5c31af7Sopenharmony_ci			params.args.push_back("--deqp-surface-type=window");
362e5c31af7Sopenharmony_ci		else if ((*cfgIter).surfaceTypes & SURFACETYPE_PBUFFER)
363e5c31af7Sopenharmony_ci			params.args.push_back("--deqp-surface-type=pbuffer");
364e5c31af7Sopenharmony_ci		else if ((*cfgIter).surfaceTypes & SURFACETYPE_PIXMAP)
365e5c31af7Sopenharmony_ci			params.args.push_back("--deqp-surface-type=pixmap");
366e5c31af7Sopenharmony_ci		runs.push_back(params);
367e5c31af7Sopenharmony_ci	}
368e5c31af7Sopenharmony_ci}
369e5c31af7Sopenharmony_ci
370e5c31af7Sopenharmony_cistatic void getTestRunsForNoContext(glu::ApiType type, vector<TestRunParams>& runs, const ConfigList& configs, const RunParams* runParams,
371e5c31af7Sopenharmony_ci									const int numRunParams, const char* mustpassDir)
372e5c31af7Sopenharmony_ci{
373e5c31af7Sopenharmony_ci	vector<Config>::const_iterator cfgIter = configs.configs.begin();
374e5c31af7Sopenharmony_ci
375e5c31af7Sopenharmony_ci	for (int i = 0; i < numRunParams; ++i)
376e5c31af7Sopenharmony_ci	{
377e5c31af7Sopenharmony_ci		if (!glu::contextSupports(glu::ContextType(type), runParams[i].apiType))
378e5c31af7Sopenharmony_ci				continue;
379e5c31af7Sopenharmony_ci
380e5c31af7Sopenharmony_ci		const char* apiName = getApiName(runParams[i].apiType);
381e5c31af7Sopenharmony_ci
382e5c31af7Sopenharmony_ci		const int width  = runParams[i].surfaceWidth;
383e5c31af7Sopenharmony_ci		const int height = runParams[i].surfaceHeight;
384e5c31af7Sopenharmony_ci		const int seed   = runParams[i].baseSeed;
385e5c31af7Sopenharmony_ci
386e5c31af7Sopenharmony_ci		TestRunParams params;
387e5c31af7Sopenharmony_ci		params.logFilename = getLogFileName(apiName, runParams[i].configName, 1, i, width, height, seed);
388e5c31af7Sopenharmony_ci
389e5c31af7Sopenharmony_ci		getBaseOptions(params.args, mustpassDir, apiName, runParams[i].configName, runParams[i].screenRotation, width,
390e5c31af7Sopenharmony_ci					   height);
391e5c31af7Sopenharmony_ci
392e5c31af7Sopenharmony_ci		params.args.push_back(string("--deqp-base-seed=") + de::toString(seed));
393e5c31af7Sopenharmony_ci
394e5c31af7Sopenharmony_ci		appendConfigArgs(*cfgIter, params.args, runParams[i].fboConfig);
395e5c31af7Sopenharmony_ci
396e5c31af7Sopenharmony_ci		runs.push_back(params);
397e5c31af7Sopenharmony_ci	}
398e5c31af7Sopenharmony_ci}
399e5c31af7Sopenharmony_ci
400e5c31af7Sopenharmony_cistatic void getTestRunsForNoContextES(glu::ApiType type, vector<TestRunParams>& runs, const ConfigList& configs)
401e5c31af7Sopenharmony_ci{
402e5c31af7Sopenharmony_ci#include "glcKhronosMustpassEsNocontext.hpp"
403e5c31af7Sopenharmony_ci	getTestRunsForNoContext(type, runs, configs, khronos_mustpass_es_nocontext_first_cfg,
404e5c31af7Sopenharmony_ci							DE_LENGTH_OF_ARRAY(khronos_mustpass_es_nocontext_first_cfg), mustpassDir);
405e5c31af7Sopenharmony_ci}
406e5c31af7Sopenharmony_ci
407e5c31af7Sopenharmony_cistatic void getTestRunsForSingleConfig(glu::ApiType type, vector<TestRunParams>& runs, const ConfigList& configs, const RunParams* runParams,
408e5c31af7Sopenharmony_ci									const int numRunParams, const char* mustpassDir)
409e5c31af7Sopenharmony_ci{
410e5c31af7Sopenharmony_ci	vector<Config>::const_iterator cfgIter = configs.configs.begin();
411e5c31af7Sopenharmony_ci
412e5c31af7Sopenharmony_ci	for (int i = 0; i < numRunParams; ++i)
413e5c31af7Sopenharmony_ci	{
414e5c31af7Sopenharmony_ci		if (type != runParams[i].apiType)
415e5c31af7Sopenharmony_ci			continue;
416e5c31af7Sopenharmony_ci
417e5c31af7Sopenharmony_ci		const char* apiName = getApiName(runParams[i].apiType);
418e5c31af7Sopenharmony_ci
419e5c31af7Sopenharmony_ci		const int width  = runParams[i].surfaceWidth;
420e5c31af7Sopenharmony_ci		const int height = runParams[i].surfaceHeight;
421e5c31af7Sopenharmony_ci		const int seed   = runParams[i].baseSeed;
422e5c31af7Sopenharmony_ci
423e5c31af7Sopenharmony_ci		TestRunParams params;
424e5c31af7Sopenharmony_ci		params.logFilename = getLogFileName(apiName, runParams[i].configName, 1, i, width, height, seed);
425e5c31af7Sopenharmony_ci
426e5c31af7Sopenharmony_ci		getBaseOptions(params.args, mustpassDir, apiName, runParams[i].configName, runParams[i].screenRotation, width,
427e5c31af7Sopenharmony_ci					   height);
428e5c31af7Sopenharmony_ci
429e5c31af7Sopenharmony_ci		params.args.push_back(string("--deqp-base-seed=") + de::toString(seed));
430e5c31af7Sopenharmony_ci
431e5c31af7Sopenharmony_ci		appendConfigArgs(*cfgIter, params.args, runParams[i].fboConfig);
432e5c31af7Sopenharmony_ci
433e5c31af7Sopenharmony_ci		runs.push_back(params);
434e5c31af7Sopenharmony_ci	}
435e5c31af7Sopenharmony_ci}
436e5c31af7Sopenharmony_cistatic void getTestRunsForSingleConfigES(glu::ApiType type, vector<TestRunParams>& runs, const ConfigList& configs)
437e5c31af7Sopenharmony_ci{
438e5c31af7Sopenharmony_ci#include "glcKhronosMustpassEsSingleConfig.hpp"
439e5c31af7Sopenharmony_ci	getTestRunsForSingleConfig(type, runs, configs, khronos_mustpass_es_single_config_first_cfg,
440e5c31af7Sopenharmony_ci							   DE_LENGTH_OF_ARRAY(khronos_mustpass_es_single_config_first_cfg), mustpassDir);
441e5c31af7Sopenharmony_ci}
442e5c31af7Sopenharmony_ci
443e5c31af7Sopenharmony_cistatic void getTestRunsForES(glu::ApiType type, const ConfigList& configs, vector<TestRunParams>& runs)
444e5c31af7Sopenharmony_ci{
445e5c31af7Sopenharmony_ci	getTestRunsForAOSPEGL(runs, configs);
446e5c31af7Sopenharmony_ci	getTestRunsForAOSPES(runs, configs, type);
447e5c31af7Sopenharmony_ci	getTestRunsForNoContextES(type, runs, configs);
448e5c31af7Sopenharmony_ci	getTestRunsForSingleConfigES(type, runs, configs);
449e5c31af7Sopenharmony_ci
450e5c31af7Sopenharmony_ci#include "glcKhronosMustpassEs.hpp"
451e5c31af7Sopenharmony_ci
452e5c31af7Sopenharmony_ci	for (vector<Config>::const_iterator cfgIter = configs.configs.begin(); cfgIter != configs.configs.end(); ++cfgIter)
453e5c31af7Sopenharmony_ci	{
454e5c31af7Sopenharmony_ci		const bool isFirst		= cfgIter == configs.configs.begin();
455e5c31af7Sopenharmony_ci		const int  numRunParams = isFirst ? DE_LENGTH_OF_ARRAY(khronos_mustpass_es_first_cfg) :
456e5c31af7Sopenharmony_ci										   DE_LENGTH_OF_ARRAY(khronos_mustpass_es_other_cfg);
457e5c31af7Sopenharmony_ci		const RunParams* runParams = isFirst ? khronos_mustpass_es_first_cfg : khronos_mustpass_es_other_cfg;
458e5c31af7Sopenharmony_ci
459e5c31af7Sopenharmony_ci		for (int runNdx = 0; runNdx < numRunParams; runNdx++)
460e5c31af7Sopenharmony_ci		{
461e5c31af7Sopenharmony_ci			if (!glu::contextSupports(glu::ContextType(type), runParams[runNdx].apiType))
462e5c31af7Sopenharmony_ci				continue;
463e5c31af7Sopenharmony_ci
464e5c31af7Sopenharmony_ci			const char* apiName = getApiName(runParams[runNdx].apiType);
465e5c31af7Sopenharmony_ci
466e5c31af7Sopenharmony_ci			const int width   = runParams[runNdx].surfaceWidth;
467e5c31af7Sopenharmony_ci			const int height  = runParams[runNdx].surfaceHeight;
468e5c31af7Sopenharmony_ci			const int seed	= runParams[runNdx].baseSeed;
469e5c31af7Sopenharmony_ci
470e5c31af7Sopenharmony_ci			TestRunParams params;
471e5c31af7Sopenharmony_ci
472e5c31af7Sopenharmony_ci			params.logFilename =
473e5c31af7Sopenharmony_ci				getLogFileName(apiName, runParams[runNdx].configName, cfgIter->id, runNdx, width, height, seed);
474e5c31af7Sopenharmony_ci
475e5c31af7Sopenharmony_ci			getBaseOptions(params.args, mustpassDir, apiName, runParams[runNdx].configName,
476e5c31af7Sopenharmony_ci						   runParams[runNdx].screenRotation, width, height);
477e5c31af7Sopenharmony_ci			params.args.push_back(string("--deqp-base-seed=") + de::toString(seed));
478e5c31af7Sopenharmony_ci
479e5c31af7Sopenharmony_ci			appendConfigArgs(*cfgIter, params.args, runParams[runNdx].fboConfig);
480e5c31af7Sopenharmony_ci
481e5c31af7Sopenharmony_ci			runs.push_back(params);
482e5c31af7Sopenharmony_ci		}
483e5c31af7Sopenharmony_ci	}
484e5c31af7Sopenharmony_ci}
485e5c31af7Sopenharmony_ci
486e5c31af7Sopenharmony_cistatic void getTestRunsForNoContextGL(glu::ApiType type, vector<TestRunParams>& runs, const ConfigList& configs)
487e5c31af7Sopenharmony_ci{
488e5c31af7Sopenharmony_ci#include "glcKhronosMustpassGlNocontext.hpp"
489e5c31af7Sopenharmony_ci	getTestRunsForNoContext(type, runs, configs, khronos_mustpass_gl_nocontext_first_cfg,
490e5c31af7Sopenharmony_ci							DE_LENGTH_OF_ARRAY(khronos_mustpass_gl_nocontext_first_cfg), mustpassDir);
491e5c31af7Sopenharmony_ci}
492e5c31af7Sopenharmony_cistatic void getTestRunsForSingleConfigGL(glu::ApiType type, vector<TestRunParams>& runs, const ConfigList& configs)
493e5c31af7Sopenharmony_ci{
494e5c31af7Sopenharmony_ci#include "glcKhronosMustpassGlSingleConfig.hpp"
495e5c31af7Sopenharmony_ci	getTestRunsForSingleConfig(type, runs, configs, khronos_mustpass_gl_single_config_first_cfg,
496e5c31af7Sopenharmony_ci							   DE_LENGTH_OF_ARRAY(khronos_mustpass_gl_single_config_first_cfg), mustpassDir);
497e5c31af7Sopenharmony_ci}
498e5c31af7Sopenharmony_ci
499e5c31af7Sopenharmony_cistatic void getTestRunsForESForGL(glu::ApiType type, vector<TestRunParams>& runs, const ConfigList& configs)
500e5c31af7Sopenharmony_ci{
501e5c31af7Sopenharmony_ci#include "glcKhronosMustpassAospForGl.hpp"
502e5c31af7Sopenharmony_ci
503e5c31af7Sopenharmony_ci	vector<Config>::const_iterator cfgIter = configs.configs.begin();
504e5c31af7Sopenharmony_ci	const int  numRunParams = DE_LENGTH_OF_ARRAY(khronos_mustpass_aosp_for_gl_first_cfg);
505e5c31af7Sopenharmony_ci	const RunParams* runParams = khronos_mustpass_aosp_for_gl_first_cfg;
506e5c31af7Sopenharmony_ci
507e5c31af7Sopenharmony_ci	for (int i = 0; i < numRunParams; ++i)
508e5c31af7Sopenharmony_ci	{
509e5c31af7Sopenharmony_ci		if (!glu::contextSupports(glu::ContextType(type), runParams[i].apiType))
510e5c31af7Sopenharmony_ci			continue;
511e5c31af7Sopenharmony_ci
512e5c31af7Sopenharmony_ci		const char* apiName = getApiName(runParams[i].apiType);
513e5c31af7Sopenharmony_ci
514e5c31af7Sopenharmony_ci		const int width  = runParams[i].surfaceWidth;
515e5c31af7Sopenharmony_ci		const int height = runParams[i].surfaceHeight;
516e5c31af7Sopenharmony_ci		const int seed   = runParams[i].baseSeed;
517e5c31af7Sopenharmony_ci
518e5c31af7Sopenharmony_ci		TestRunParams params;
519e5c31af7Sopenharmony_ci		params.logFilename = getLogFileName(apiName, runParams[i].configName, 1, i, width, height, seed);
520e5c31af7Sopenharmony_ci
521e5c31af7Sopenharmony_ci		getBaseOptions(params.args, mustpassDir, apiName, runParams[i].configName, runParams[i].screenRotation, width,
522e5c31af7Sopenharmony_ci					   height);
523e5c31af7Sopenharmony_ci
524e5c31af7Sopenharmony_ci		params.args.push_back(string("--deqp-base-seed=") + de::toString(seed));
525e5c31af7Sopenharmony_ci
526e5c31af7Sopenharmony_ci		appendConfigArgs(*cfgIter, params.args, runParams[i].fboConfig);
527e5c31af7Sopenharmony_ci
528e5c31af7Sopenharmony_ci		runs.push_back(params);
529e5c31af7Sopenharmony_ci	}
530e5c31af7Sopenharmony_ci}
531e5c31af7Sopenharmony_ci
532e5c31af7Sopenharmony_ci
533e5c31af7Sopenharmony_cistatic void getTestRunsForGL(glu::ApiType type, const ConfigList& configs, vector<TestRunParams>& runs)
534e5c31af7Sopenharmony_ci{
535e5c31af7Sopenharmony_ci	getTestRunsForESForGL(type, runs, configs);
536e5c31af7Sopenharmony_ci	getTestRunsForNoContextGL(type, runs, configs);
537e5c31af7Sopenharmony_ci	getTestRunsForSingleConfigGL(type, runs, configs);
538e5c31af7Sopenharmony_ci#include "glcKhronosMustpassGl.hpp"
539e5c31af7Sopenharmony_ci
540e5c31af7Sopenharmony_ci	for (vector<Config>::const_iterator cfgIter = configs.configs.begin(); cfgIter != configs.configs.end(); ++cfgIter)
541e5c31af7Sopenharmony_ci	{
542e5c31af7Sopenharmony_ci		const bool isFirst		= cfgIter == configs.configs.begin();
543e5c31af7Sopenharmony_ci		const int  numRunParams = isFirst ? DE_LENGTH_OF_ARRAY(khronos_mustpass_gl_first_cfg) :
544e5c31af7Sopenharmony_ci										   DE_LENGTH_OF_ARRAY(khronos_mustpass_gl_other_cfg);
545e5c31af7Sopenharmony_ci		const RunParams* runParams = isFirst ? khronos_mustpass_gl_first_cfg : khronos_mustpass_gl_other_cfg;
546e5c31af7Sopenharmony_ci
547e5c31af7Sopenharmony_ci		for (int runNdx = 0; runNdx < numRunParams; runNdx++)
548e5c31af7Sopenharmony_ci		{
549e5c31af7Sopenharmony_ci			if (type != runParams[runNdx].apiType)
550e5c31af7Sopenharmony_ci				continue;
551e5c31af7Sopenharmony_ci
552e5c31af7Sopenharmony_ci			const char* apiName = getApiName(runParams[runNdx].apiType);
553e5c31af7Sopenharmony_ci
554e5c31af7Sopenharmony_ci			const int width   = runParams[runNdx].surfaceWidth;
555e5c31af7Sopenharmony_ci			const int height  = runParams[runNdx].surfaceHeight;
556e5c31af7Sopenharmony_ci			const int seed	= runParams[runNdx].baseSeed;
557e5c31af7Sopenharmony_ci
558e5c31af7Sopenharmony_ci			TestRunParams params;
559e5c31af7Sopenharmony_ci
560e5c31af7Sopenharmony_ci			params.logFilename =
561e5c31af7Sopenharmony_ci				getLogFileName(apiName, runParams[runNdx].configName, cfgIter->id, runNdx, width, height, seed);
562e5c31af7Sopenharmony_ci
563e5c31af7Sopenharmony_ci			getBaseOptions(params.args, mustpassDir, apiName, runParams[runNdx].configName,
564e5c31af7Sopenharmony_ci						   runParams[runNdx].screenRotation, width, height);
565e5c31af7Sopenharmony_ci			params.args.push_back(string("--deqp-base-seed=") + de::toString(seed));
566e5c31af7Sopenharmony_ci
567e5c31af7Sopenharmony_ci			appendConfigArgs(*cfgIter, params.args, runParams[runNdx].fboConfig);
568e5c31af7Sopenharmony_ci
569e5c31af7Sopenharmony_ci			runs.push_back(params);
570e5c31af7Sopenharmony_ci		}
571e5c31af7Sopenharmony_ci	}
572e5c31af7Sopenharmony_ci}
573e5c31af7Sopenharmony_ci
574e5c31af7Sopenharmony_cistatic void getTestRunParams(glu::ApiType type, const ConfigList& configs, vector<TestRunParams>& runs)
575e5c31af7Sopenharmony_ci{
576e5c31af7Sopenharmony_ci	switch (type.getProfile())
577e5c31af7Sopenharmony_ci	{
578e5c31af7Sopenharmony_ci	case glu::PROFILE_CORE:
579e5c31af7Sopenharmony_ci		getTestRunsForGL(type, configs, runs);
580e5c31af7Sopenharmony_ci		break;
581e5c31af7Sopenharmony_ci	case glu::PROFILE_ES:
582e5c31af7Sopenharmony_ci		getTestRunsForES(type, configs, runs);
583e5c31af7Sopenharmony_ci		break;
584e5c31af7Sopenharmony_ci	default:
585e5c31af7Sopenharmony_ci		throw std::runtime_error("Unknown context type");
586e5c31af7Sopenharmony_ci	}
587e5c31af7Sopenharmony_ci}
588e5c31af7Sopenharmony_ci
589e5c31af7Sopenharmony_cistruct FileDeleter
590e5c31af7Sopenharmony_ci{
591e5c31af7Sopenharmony_ci	void operator()(FILE* file) const
592e5c31af7Sopenharmony_ci	{
593e5c31af7Sopenharmony_ci		if (file)
594e5c31af7Sopenharmony_ci			fclose(file);
595e5c31af7Sopenharmony_ci	}
596e5c31af7Sopenharmony_ci};
597e5c31af7Sopenharmony_ci
598e5c31af7Sopenharmony_cistruct XmlWriterDeleter
599e5c31af7Sopenharmony_ci{
600e5c31af7Sopenharmony_ci	void operator()(qpXmlWriter* writer) const
601e5c31af7Sopenharmony_ci	{
602e5c31af7Sopenharmony_ci		if (writer)
603e5c31af7Sopenharmony_ci			qpXmlWriter_destroy(writer);
604e5c31af7Sopenharmony_ci	}
605e5c31af7Sopenharmony_ci};
606e5c31af7Sopenharmony_ci
607e5c31af7Sopenharmony_cistatic const char* getRunTypeName(glu::ApiType type)
608e5c31af7Sopenharmony_ci{
609e5c31af7Sopenharmony_ci	if (type == glu::ApiType::es(2, 0))
610e5c31af7Sopenharmony_ci		return "es2";
611e5c31af7Sopenharmony_ci	else if (type == glu::ApiType::es(3, 0))
612e5c31af7Sopenharmony_ci		return "es3";
613e5c31af7Sopenharmony_ci	else if (type == glu::ApiType::es(3, 1))
614e5c31af7Sopenharmony_ci		return "es31";
615e5c31af7Sopenharmony_ci	else if (type == glu::ApiType::es(3, 2))
616e5c31af7Sopenharmony_ci		return "es32";
617e5c31af7Sopenharmony_ci	else if (type == glu::ApiType::core(3, 0))
618e5c31af7Sopenharmony_ci		return "gl30";
619e5c31af7Sopenharmony_ci	else if (type == glu::ApiType::core(3, 1))
620e5c31af7Sopenharmony_ci		return "gl31";
621e5c31af7Sopenharmony_ci	else if (type == glu::ApiType::core(3, 2))
622e5c31af7Sopenharmony_ci		return "gl32";
623e5c31af7Sopenharmony_ci	else if (type == glu::ApiType::core(3, 3))
624e5c31af7Sopenharmony_ci		return "gl33";
625e5c31af7Sopenharmony_ci	else if (type == glu::ApiType::core(4, 0))
626e5c31af7Sopenharmony_ci		return "gl40";
627e5c31af7Sopenharmony_ci	else if (type == glu::ApiType::core(4, 1))
628e5c31af7Sopenharmony_ci		return "gl41";
629e5c31af7Sopenharmony_ci	else if (type == glu::ApiType::core(4, 2))
630e5c31af7Sopenharmony_ci		return "gl42";
631e5c31af7Sopenharmony_ci	else if (type == glu::ApiType::core(4, 3))
632e5c31af7Sopenharmony_ci		return "gl43";
633e5c31af7Sopenharmony_ci	else if (type == glu::ApiType::core(4, 4))
634e5c31af7Sopenharmony_ci		return "gl44";
635e5c31af7Sopenharmony_ci	else if (type == glu::ApiType::core(4, 5))
636e5c31af7Sopenharmony_ci		return "gl45";
637e5c31af7Sopenharmony_ci	else if (type == glu::ApiType::core(4, 6))
638e5c31af7Sopenharmony_ci		return "gl46";
639e5c31af7Sopenharmony_ci	else
640e5c31af7Sopenharmony_ci		return DE_NULL;
641e5c31af7Sopenharmony_ci}
642e5c31af7Sopenharmony_ci
643e5c31af7Sopenharmony_ci#define XML_CHECK(X) \
644e5c31af7Sopenharmony_ci	if (!(X))        \
645e5c31af7Sopenharmony_ci	throw tcu::Exception("Writing XML failed")
646e5c31af7Sopenharmony_ci
647e5c31af7Sopenharmony_cistatic void writeRunSummary(const TestRunSummary& summary, const char* filename)
648e5c31af7Sopenharmony_ci{
649e5c31af7Sopenharmony_ci	de::UniquePtr<FILE, FileDeleter> out(fopen(filename, "wb"));
650e5c31af7Sopenharmony_ci	if (!out)
651e5c31af7Sopenharmony_ci		throw tcu::Exception(string("Failed to open ") + filename);
652e5c31af7Sopenharmony_ci
653e5c31af7Sopenharmony_ci	de::UniquePtr<qpXmlWriter, XmlWriterDeleter> writer(qpXmlWriter_createFileWriter(out.get(), DE_FALSE, DE_FALSE));
654e5c31af7Sopenharmony_ci	if (!writer)
655e5c31af7Sopenharmony_ci		throw std::bad_alloc();
656e5c31af7Sopenharmony_ci
657e5c31af7Sopenharmony_ci	XML_CHECK(qpXmlWriter_startDocument(writer.get(), true));
658e5c31af7Sopenharmony_ci
659e5c31af7Sopenharmony_ci	{
660e5c31af7Sopenharmony_ci		qpXmlAttribute attribs[2];
661e5c31af7Sopenharmony_ci
662e5c31af7Sopenharmony_ci		attribs[0] = qpSetStringAttrib("Type", getRunTypeName(summary.runType));
663e5c31af7Sopenharmony_ci		attribs[1] = qpSetBoolAttrib("Conformant", summary.isConformant ? DE_TRUE : DE_FALSE);
664e5c31af7Sopenharmony_ci
665e5c31af7Sopenharmony_ci		XML_CHECK(qpXmlWriter_startElement(writer.get(), "Summary", DE_LENGTH_OF_ARRAY(attribs), attribs));
666e5c31af7Sopenharmony_ci	}
667e5c31af7Sopenharmony_ci
668e5c31af7Sopenharmony_ci	// Config run
669e5c31af7Sopenharmony_ci	{
670e5c31af7Sopenharmony_ci		qpXmlAttribute attribs[1];
671e5c31af7Sopenharmony_ci		attribs[0] = qpSetStringAttrib("FileName", summary.configLogFilename.c_str());
672e5c31af7Sopenharmony_ci		XML_CHECK(qpXmlWriter_startElement(writer.get(), "Configs", DE_LENGTH_OF_ARRAY(attribs), attribs) &&
673e5c31af7Sopenharmony_ci				  qpXmlWriter_endElement(writer.get(), "Configs"));
674e5c31af7Sopenharmony_ci	}
675e5c31af7Sopenharmony_ci
676e5c31af7Sopenharmony_ci	// Record test run parameters (log filename & command line).
677e5c31af7Sopenharmony_ci	for (vector<TestRunParams>::const_iterator runIter = summary.runParams.begin(); runIter != summary.runParams.end();
678e5c31af7Sopenharmony_ci		 ++runIter)
679e5c31af7Sopenharmony_ci	{
680e5c31af7Sopenharmony_ci		string		   cmdLine;
681e5c31af7Sopenharmony_ci		qpXmlAttribute attribs[2];
682e5c31af7Sopenharmony_ci
683e5c31af7Sopenharmony_ci		for (vector<string>::const_iterator argIter = runIter->args.begin(); argIter != runIter->args.end(); ++argIter)
684e5c31af7Sopenharmony_ci		{
685e5c31af7Sopenharmony_ci			if (argIter != runIter->args.begin())
686e5c31af7Sopenharmony_ci				cmdLine += " ";
687e5c31af7Sopenharmony_ci			cmdLine += *argIter;
688e5c31af7Sopenharmony_ci		}
689e5c31af7Sopenharmony_ci
690e5c31af7Sopenharmony_ci		attribs[0] = qpSetStringAttrib("FileName", runIter->logFilename.c_str());
691e5c31af7Sopenharmony_ci		attribs[1] = qpSetStringAttrib("CmdLine", cmdLine.c_str());
692e5c31af7Sopenharmony_ci
693e5c31af7Sopenharmony_ci		XML_CHECK(qpXmlWriter_startElement(writer.get(), "TestRun", DE_LENGTH_OF_ARRAY(attribs), attribs) &&
694e5c31af7Sopenharmony_ci				  qpXmlWriter_endElement(writer.get(), "TestRun"));
695e5c31af7Sopenharmony_ci	}
696e5c31af7Sopenharmony_ci
697e5c31af7Sopenharmony_ci	XML_CHECK(qpXmlWriter_endElement(writer.get(), "Summary"));
698e5c31af7Sopenharmony_ci	XML_CHECK(qpXmlWriter_endDocument(writer.get()));
699e5c31af7Sopenharmony_ci}
700e5c31af7Sopenharmony_ci
701e5c31af7Sopenharmony_ci#undef XML_CHECK
702e5c31af7Sopenharmony_ci
703e5c31af7Sopenharmony_ciTestRunner::TestRunner(tcu::Platform& platform, tcu::Archive& archive, const char* waiverPath,
704e5c31af7Sopenharmony_ci					   const char* logDirPath, glu::ApiType type, deUint32 flags)
705e5c31af7Sopenharmony_ci	: m_platform(platform)
706e5c31af7Sopenharmony_ci	, m_archive(archive)
707e5c31af7Sopenharmony_ci	, m_waiverPath(waiverPath)
708e5c31af7Sopenharmony_ci	, m_logDirPath(logDirPath)
709e5c31af7Sopenharmony_ci	, m_type(type)
710e5c31af7Sopenharmony_ci	, m_flags(flags)
711e5c31af7Sopenharmony_ci	, m_iterState(ITERATE_INIT)
712e5c31af7Sopenharmony_ci	, m_curSession(DE_NULL)
713e5c31af7Sopenharmony_ci	, m_sessionsExecuted(0)
714e5c31af7Sopenharmony_ci	, m_sessionsPassed(0)
715e5c31af7Sopenharmony_ci	, m_sessionsFailed(0)
716e5c31af7Sopenharmony_ci{
717e5c31af7Sopenharmony_ci}
718e5c31af7Sopenharmony_ci
719e5c31af7Sopenharmony_ciTestRunner::~TestRunner(void)
720e5c31af7Sopenharmony_ci{
721e5c31af7Sopenharmony_ci	delete m_curSession;
722e5c31af7Sopenharmony_ci}
723e5c31af7Sopenharmony_ci
724e5c31af7Sopenharmony_cibool TestRunner::iterate(void)
725e5c31af7Sopenharmony_ci{
726e5c31af7Sopenharmony_ci	switch (m_iterState)
727e5c31af7Sopenharmony_ci	{
728e5c31af7Sopenharmony_ci	case ITERATE_INIT:
729e5c31af7Sopenharmony_ci		init();
730e5c31af7Sopenharmony_ci		m_iterState = (m_sessionIter != m_runSessions.end()) ? ITERATE_INIT_SESSION : ITERATE_DEINIT;
731e5c31af7Sopenharmony_ci		return true;
732e5c31af7Sopenharmony_ci
733e5c31af7Sopenharmony_ci	case ITERATE_DEINIT:
734e5c31af7Sopenharmony_ci		deinit();
735e5c31af7Sopenharmony_ci		m_iterState = ITERATE_INIT;
736e5c31af7Sopenharmony_ci		return false;
737e5c31af7Sopenharmony_ci
738e5c31af7Sopenharmony_ci	case ITERATE_INIT_SESSION:
739e5c31af7Sopenharmony_ci		DE_ASSERT(m_sessionIter != m_runSessions.end());
740e5c31af7Sopenharmony_ci		initSession(*m_sessionIter);
741e5c31af7Sopenharmony_ci		if (m_flags & PRINT_SUMMARY)
742e5c31af7Sopenharmony_ci			m_iterState = ITERATE_DEINIT_SESSION;
743e5c31af7Sopenharmony_ci		else
744e5c31af7Sopenharmony_ci			m_iterState = ITERATE_ITERATE_SESSION;
745e5c31af7Sopenharmony_ci		return true;
746e5c31af7Sopenharmony_ci
747e5c31af7Sopenharmony_ci	case ITERATE_DEINIT_SESSION:
748e5c31af7Sopenharmony_ci		deinitSession();
749e5c31af7Sopenharmony_ci		++m_sessionIter;
750e5c31af7Sopenharmony_ci		m_iterState = (m_sessionIter != m_runSessions.end()) ? ITERATE_INIT_SESSION : ITERATE_DEINIT;
751e5c31af7Sopenharmony_ci		return true;
752e5c31af7Sopenharmony_ci
753e5c31af7Sopenharmony_ci	case ITERATE_ITERATE_SESSION:
754e5c31af7Sopenharmony_ci		if (!iterateSession())
755e5c31af7Sopenharmony_ci			m_iterState = ITERATE_DEINIT_SESSION;
756e5c31af7Sopenharmony_ci		return true;
757e5c31af7Sopenharmony_ci
758e5c31af7Sopenharmony_ci	default:
759e5c31af7Sopenharmony_ci		DE_ASSERT(false);
760e5c31af7Sopenharmony_ci		return false;
761e5c31af7Sopenharmony_ci	}
762e5c31af7Sopenharmony_ci}
763e5c31af7Sopenharmony_ci
764e5c31af7Sopenharmony_civoid TestRunner::init(void)
765e5c31af7Sopenharmony_ci{
766e5c31af7Sopenharmony_ci	DE_ASSERT(m_runSessions.empty() && m_summary.runParams.empty());
767e5c31af7Sopenharmony_ci
768e5c31af7Sopenharmony_ci	tcu::print("Running %s conformance\n", glu::getApiTypeDescription(m_type));
769e5c31af7Sopenharmony_ci
770e5c31af7Sopenharmony_ci	m_summary.runType = m_type;
771e5c31af7Sopenharmony_ci
772e5c31af7Sopenharmony_ci	// Get list of configs to test.
773e5c31af7Sopenharmony_ci	ConfigList configList;
774e5c31af7Sopenharmony_ci	getDefaultConfigList(m_platform, m_type, configList);
775e5c31af7Sopenharmony_ci
776e5c31af7Sopenharmony_ci	tcu::print("  found %d compatible and %d excluded configs\n", (int)configList.configs.size(),
777e5c31af7Sopenharmony_ci			   (int)configList.excludedConfigs.size());
778e5c31af7Sopenharmony_ci
779e5c31af7Sopenharmony_ci	// Config list run.
780e5c31af7Sopenharmony_ci	{
781e5c31af7Sopenharmony_ci		const char*   configLogFilename = "configs.qpa";
782e5c31af7Sopenharmony_ci		TestRunParams configRun;
783e5c31af7Sopenharmony_ci
784e5c31af7Sopenharmony_ci		configRun.logFilename = configLogFilename;
785e5c31af7Sopenharmony_ci		configRun.args.push_back("--deqp-case=CTS-Configs.*");
786e5c31af7Sopenharmony_ci		m_runSessions.push_back(configRun);
787e5c31af7Sopenharmony_ci
788e5c31af7Sopenharmony_ci		m_summary.configLogFilename = configLogFilename;
789e5c31af7Sopenharmony_ci	}
790e5c31af7Sopenharmony_ci
791e5c31af7Sopenharmony_ci	// Conformance test type specific runs
792e5c31af7Sopenharmony_ci	getTestRunParams(m_type, configList, m_runSessions);
793e5c31af7Sopenharmony_ci
794e5c31af7Sopenharmony_ci	// Record run params for summary.
795e5c31af7Sopenharmony_ci	for (std::vector<TestRunParams>::const_iterator runIter = m_runSessions.begin() + 1; runIter != m_runSessions.end();
796e5c31af7Sopenharmony_ci		 ++runIter)
797e5c31af7Sopenharmony_ci		m_summary.runParams.push_back(*runIter);
798e5c31af7Sopenharmony_ci
799e5c31af7Sopenharmony_ci	// Session iterator
800e5c31af7Sopenharmony_ci	m_sessionIter = m_runSessions.begin();
801e5c31af7Sopenharmony_ci}
802e5c31af7Sopenharmony_ci
803e5c31af7Sopenharmony_civoid TestRunner::deinit(void)
804e5c31af7Sopenharmony_ci{
805e5c31af7Sopenharmony_ci	// Print out totals.
806e5c31af7Sopenharmony_ci	bool isConformant_ = m_sessionsExecuted == m_sessionsPassed;
807e5c31af7Sopenharmony_ci	DE_ASSERT(m_sessionsExecuted == m_sessionsPassed + m_sessionsFailed);
808e5c31af7Sopenharmony_ci	tcu::print("\n%d/%d sessions passed, conformance test %s\n", m_sessionsPassed, m_sessionsExecuted,
809e5c31af7Sopenharmony_ci			   isConformant_ ? "PASSED" : "FAILED");
810e5c31af7Sopenharmony_ci
811e5c31af7Sopenharmony_ci	m_summary.isConformant = isConformant_;
812e5c31af7Sopenharmony_ci
813e5c31af7Sopenharmony_ci	// Write out summary.
814e5c31af7Sopenharmony_ci	writeRunSummary(m_summary, de::FilePath::join(m_logDirPath, "cts-run-summary.xml").getPath());
815e5c31af7Sopenharmony_ci
816e5c31af7Sopenharmony_ci	m_runSessions.clear();
817e5c31af7Sopenharmony_ci}
818e5c31af7Sopenharmony_ci
819e5c31af7Sopenharmony_civoid TestRunner::initSession(const TestRunParams& runParams)
820e5c31af7Sopenharmony_ci{
821e5c31af7Sopenharmony_ci	DE_ASSERT(!m_curSession);
822e5c31af7Sopenharmony_ci
823e5c31af7Sopenharmony_ci	tcu::print("\n  Test run %d / %d\n", (int)(m_sessionIter - m_runSessions.begin() + 1), (int)m_runSessions.size());
824e5c31af7Sopenharmony_ci
825e5c31af7Sopenharmony_ci	// Compute final args for run.
826e5c31af7Sopenharmony_ci	vector<string> args(runParams.args);
827e5c31af7Sopenharmony_ci	args.push_back(string("--deqp-log-filename=") + de::FilePath::join(m_logDirPath, runParams.logFilename).getPath());
828e5c31af7Sopenharmony_ci
829e5c31af7Sopenharmony_ci	if (!(m_flags & VERBOSE_IMAGES))
830e5c31af7Sopenharmony_ci		args.push_back("--deqp-log-images=disable");
831e5c31af7Sopenharmony_ci
832e5c31af7Sopenharmony_ci	if (!(m_flags & VERBOSE_SHADERS))
833e5c31af7Sopenharmony_ci		args.push_back("--deqp-log-shader-sources=disable");
834e5c31af7Sopenharmony_ci
835e5c31af7Sopenharmony_ci	if (!m_waiverPath.empty())
836e5c31af7Sopenharmony_ci		args.push_back(string("--deqp-waiver-file=") + m_waiverPath);
837e5c31af7Sopenharmony_ci
838e5c31af7Sopenharmony_ci	std::ostringstream			  ostr;
839e5c31af7Sopenharmony_ci	std::ostream_iterator<string> out_it(ostr, ", ");
840e5c31af7Sopenharmony_ci	std::copy(args.begin(), args.end(), out_it);
841e5c31af7Sopenharmony_ci	tcu::print("\n  Config: %s \n\n", ostr.str().c_str());
842e5c31af7Sopenharmony_ci
843e5c31af7Sopenharmony_ci	// Translate to argc, argv
844e5c31af7Sopenharmony_ci	vector<const char*> argv;
845e5c31af7Sopenharmony_ci	argv.push_back("cts-runner"); // Assumed binary name
846e5c31af7Sopenharmony_ci	for (vector<string>::const_iterator i = args.begin(); i != args.end(); i++)
847e5c31af7Sopenharmony_ci		argv.push_back(i->c_str());
848e5c31af7Sopenharmony_ci
849e5c31af7Sopenharmony_ci	// Create session
850e5c31af7Sopenharmony_ci	m_curSession = new RunSession(m_platform, m_archive, (int)argv.size(), &argv[0]);
851e5c31af7Sopenharmony_ci}
852e5c31af7Sopenharmony_ci
853e5c31af7Sopenharmony_civoid TestRunner::deinitSession(void)
854e5c31af7Sopenharmony_ci{
855e5c31af7Sopenharmony_ci	DE_ASSERT(m_curSession);
856e5c31af7Sopenharmony_ci
857e5c31af7Sopenharmony_ci	// Collect results.
858e5c31af7Sopenharmony_ci	// \note NotSupported is treated as pass.
859e5c31af7Sopenharmony_ci	const tcu::TestRunStatus& result = m_curSession->getResult();
860e5c31af7Sopenharmony_ci	bool isOk = result.numFailed == 0 && result.isComplete;
861e5c31af7Sopenharmony_ci
862e5c31af7Sopenharmony_ci	DE_ASSERT(result.numExecuted == result.numPassed + result.numFailed + result.numNotSupported + result.numWarnings + result.numWaived);
863e5c31af7Sopenharmony_ci
864e5c31af7Sopenharmony_ci	m_sessionsExecuted += 1;
865e5c31af7Sopenharmony_ci	(isOk ? m_sessionsPassed : m_sessionsFailed) += 1;
866e5c31af7Sopenharmony_ci
867e5c31af7Sopenharmony_ci	delete m_curSession;
868e5c31af7Sopenharmony_ci	m_curSession = DE_NULL;
869e5c31af7Sopenharmony_ci}
870e5c31af7Sopenharmony_ci
871e5c31af7Sopenharmony_ciinline bool TestRunner::iterateSession(void)
872e5c31af7Sopenharmony_ci{
873e5c31af7Sopenharmony_ci	return m_curSession->iterate();
874e5c31af7Sopenharmony_ci}
875e5c31af7Sopenharmony_ci
876e5c31af7Sopenharmony_ci} // glcts
877