• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  * Copyright (c) 2023 LunarG, Inc.
7  * Copyright (c) 2023 Nintendo
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Vulkan Test Package
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vktTestPackage.hpp"
27 
28 #include "qpDebugOut.h"
29 #include "qpInfo.h"
30 
31 #include "tcuPlatform.hpp"
32 #include "tcuTestCase.hpp"
33 #include "tcuTestLog.hpp"
34 #include "tcuCommandLine.hpp"
35 #include "tcuWaiverUtil.hpp"
36 
37 #include "vkPlatform.hpp"
38 #include "vkPrograms.hpp"
39 #include "vkBinaryRegistry.hpp"
40 #include "vkShaderToSpirV.hpp"
41 #include "vkDebugReportUtil.hpp"
42 #include "vkQueryUtil.hpp"
43 #include "vkApiVersion.hpp"
44 #include "vkRenderDocUtil.hpp"
45 #include "vkResourceInterface.hpp"
46 
47 #include "deUniquePtr.hpp"
48 #include "deSharedPtr.hpp"
49 #ifdef CTS_USES_VULKANSC
50 	#include "deProcess.h"
51 	#include "vksClient.hpp"
52 	#include "vksIPC.hpp"
53 #endif // CTS_USES_VULKANSC
54 
55 #include "vktTestGroupUtil.hpp"
56 #include "vktApiTests.hpp"
57 #include "vktPipelineTests.hpp"
58 #include "vktBindingModelTests.hpp"
59 #include "vktSpvAsmTests.hpp"
60 #include "vktShaderLibrary.hpp"
61 #include "vktRenderPassTests.hpp"
62 #include "vktMemoryTests.hpp"
63 #include "vktShaderRenderBuiltinVarTests.hpp"
64 #include "vktShaderRenderDerivateTests.hpp"
65 #include "vktShaderRenderDiscardTests.hpp"
66 #include "vktShaderRenderIndexingTests.hpp"
67 #include "vktShaderRenderInvarianceTests.hpp"
68 #include "vktShaderRenderLimitTests.hpp"
69 #include "vktShaderRenderLoopTests.hpp"
70 #include "vktShaderRenderMatrixTests.hpp"
71 #include "vktShaderRenderOperatorTests.hpp"
72 #include "vktShaderRenderReturnTests.hpp"
73 #include "vktShaderRenderStructTests.hpp"
74 #include "vktShaderRenderSwitchTests.hpp"
75 #include "vktShaderRenderTextureFunctionTests.hpp"
76 #include "vktShaderRenderTextureGatherTests.hpp"
77 #include "vktShaderBuiltinTests.hpp"
78 #include "vktOpaqueTypeIndexingTests.hpp"
79 #include "vktAtomicOperationTests.hpp"
80 #include "vktUniformBlockTests.hpp"
81 #include "vktDynamicStateTests.hpp"
82 #include "vktSSBOLayoutTests.hpp"
83 #include "vktQueryPoolTests.hpp"
84 #include "vktDrawTests.hpp"
85 #include "vktComputeTests.hpp"
86 #include "vktConditionalTests.hpp"
87 #include "vktImageTests.hpp"
88 #include "vktInfoTests.hpp"
89 #include "vktWsiTests.hpp"
90 #include "vktSynchronizationTests.hpp"
91 #include "vktSparseResourcesTests.hpp"
92 #include "vktTessellationTests.hpp"
93 #include "vktRasterizationTests.hpp"
94 #include "vktClippingTests.hpp"
95 #include "vktFragmentOperationsTests.hpp"
96 #include "vktTextureTests.hpp"
97 #include "vktGeometryTests.hpp"
98 #include "vktRobustnessTests.hpp"
99 #include "vktMultiViewTests.hpp"
100 #include "vktSubgroupsTests.hpp"
101 #include "vktYCbCrTests.hpp"
102 #include "vktProtectedMemTests.hpp"
103 #include "vktDeviceGroupTests.hpp"
104 #include "vktMemoryModelTests.hpp"
105 #include "vktAmberGraphicsFuzzTests.hpp"
106 #include "vktAmberGlslTests.hpp"
107 #include "vktAmberDepthTests.hpp"
108 #include "vktImagelessFramebufferTests.hpp"
109 #include "vktTransformFeedbackTests.hpp"
110 #include "vktDescriptorIndexingTests.hpp"
111 #include "vktImagelessFramebufferTests.hpp"
112 #include "vktFragmentShaderInterlockTests.hpp"
113 #include "vktShaderClockTests.hpp"
114 #include "vktModifiersTests.hpp"
115 #include "vktRayTracingTests.hpp"
116 #include "vktRayQueryTests.hpp"
117 #include "vktPostmortemTests.hpp"
118 #include "vktFragmentShadingRateTests.hpp"
119 #include "vktReconvergenceTests.hpp"
120 #include "vktMeshShaderTests.hpp"
121 #include "vktFragmentShadingBarycentricTests.hpp"
122 
123 #ifndef DEQP_EXCLUDE_VK_VIDEO_TESTS
124 #include "vktVideoTests.hpp"
125 #endif // DEQP_EXCLUDE_VK_VIDEO_TESTS
126 
127 #ifdef CTS_USES_VULKANSC
128 #include "vktSafetyCriticalTests.hpp"
129 #endif // CTS_USES_VULKANSC
130 #include "vktVideoTests.hpp"
131 #include "vktShaderObjectTests.hpp"
132 
133 #include <vector>
134 #include <sstream>
135 #include <fstream>
136 #include <thread>
137 
138 namespace vkt
139 {
140 
141 using std::vector;
142 using de::UniquePtr;
143 using de::SharedPtr;
144 using de::MovePtr;
145 using tcu::TestLog;
146 
147 // TestCaseExecutor
148 
149 #ifdef CTS_USES_VULKANSC
150 struct DetailedSubprocessTestCount
151 {
152 	std::string									testPattern;
153 	int											testCount;
154 };
155 #endif // CTS_USES_VULKANSC
156 
157 class TestCaseExecutor : public tcu::TestCaseExecutor
158 {
159 public:
160 												TestCaseExecutor			(tcu::TestContext& testCtx);
161 												~TestCaseExecutor			(void);
162 
163 	void										init						(tcu::TestCase* testCase, const std::string& path) override;
164 	void										deinit						(tcu::TestCase* testCase) override;
165 
166 	tcu::TestNode::IterateResult				iterate						(tcu::TestCase* testCase) override;
167 
168 	void										deinitTestPackage			(tcu::TestContext& testCtx) override;
169 	bool										usesLocalStatus				() override;
170 	void										updateGlobalStatus			(tcu::TestRunStatus& status) override;
171 	void										reportDurations				(tcu::TestContext& testCtx, const std::string& packageName, const deInt64& duration, const std::map<std::string, deUint64>& groupsDurationTime) override;
172 	int											getCurrentSubprocessCount	(const std::string& casePath, int defaultSubprocessCount);
173 
174 private:
175 	void										logUnusedShaders		(tcu::TestCase* testCase);
176 
177 	void										runTestsInSubprocess	(tcu::TestContext& testCtx);
178 
179 	bool										spirvVersionSupported	(vk::SpirvVersion);
180 
181 	vk::BinaryCollection						m_progCollection;
182 	vk::BinaryRegistryReader					m_prebuiltBinRegistry;
183 
184 	const UniquePtr<vk::Library>				m_library;
185 	MovePtr<Context>							m_context;
186 
187 	const UniquePtr<vk::RenderDocUtil>			m_renderDoc;
188 	SharedPtr<vk::ResourceInterface>			m_resourceInterface;
189 	vk::VkPhysicalDeviceProperties				m_deviceProperties;
190 	tcu::WaiverUtil								m_waiverMechanism;
191 
192 	TestInstance*								m_instance;			//!< Current test case instance
193 	std::vector<std::string>					m_testsForSubprocess;
194 	tcu::TestRunStatus							m_status;
195 
196 #ifdef CTS_USES_VULKANSC
197 	int											m_subprocessCount;
198 
199 	std::unique_ptr<vksc_server::ipc::Parent>	m_parentIPC;
200 	std::vector<DetailedSubprocessTestCount>	m_detailedSubprocessTestCount;
201 #endif // CTS_USES_VULKANSC
202 };
203 
204 #ifdef CTS_USES_VULKANSC
supressedWrite(int,const char *)205 static deBool	supressedWrite			(int, const char*)								{ return false; }
supressedWriteFtm(int,const char *,va_list)206 static deBool	supressedWriteFtm		(int, const char*, va_list)						{ return false; }
openWrite(int type,const char * message)207 static deBool	openWrite				(int type, const char* message)					{ DE_UNREF(type); DE_UNREF(message); return true; }
openWriteFtm(int type,const char * format,va_list args)208 static deBool	openWriteFtm			(int type, const char* format, va_list args)	{ DE_UNREF(type); DE_UNREF(format); DE_UNREF(args); return true; }
suppressStandardOutput()209 static void		suppressStandardOutput	()												{ qpRedirectOut(supressedWrite, supressedWriteFtm); }
restoreStandardOutput()210 static void		restoreStandardOutput	()												{ qpRedirectOut(openWrite, openWriteFtm); }
211 #endif // CTS_USES_VULKANSC
212 
createLibrary(tcu::TestContext & testCtx)213 static MovePtr<vk::Library> createLibrary (tcu::TestContext& testCtx)
214 {
215 #ifdef DE_PLATFORM_USE_LIBRARY_TYPE
216 	return MovePtr<vk::Library>(testCtx.getPlatform().getVulkanPlatform().createLibrary(vk::Platform::LIBRARY_TYPE_VULKAN, testCtx.getCommandLine().getVkLibraryPath()));
217 #else
218 	return MovePtr<vk::Library>(testCtx.getPlatform().getVulkanPlatform().createLibrary(testCtx.getCommandLine().getVkLibraryPath()));
219 #endif
220 }
221 
getPhysicalDeviceProperties(vkt::Context & context)222 static vk::VkPhysicalDeviceProperties getPhysicalDeviceProperties(vkt::Context& context)
223 {
224 	const vk::InstanceInterface&	vki				= context.getInstanceInterface();
225 	const vk::VkPhysicalDevice		physicalDevice	= context.getPhysicalDevice();
226 
227 	vk::VkPhysicalDeviceProperties	properties;
228 	vki.getPhysicalDeviceProperties(physicalDevice, &properties);
229 	return properties;
230 }
231 
trim(const std::string & original)232 std::string trim (const std::string& original)
233 {
234 	static const std::string whiteSigns = " \t";
235 	const auto beg = original.find_first_not_of(whiteSigns);
236 	if (beg == std::string::npos)
237 		return std::string();
238 	const auto end = original.find_last_not_of(whiteSigns);
239 	return original.substr(beg, end - beg + 1);
240 }
241 
TestCaseExecutor(tcu::TestContext & testCtx)242 TestCaseExecutor::TestCaseExecutor (tcu::TestContext& testCtx)
243 	: m_prebuiltBinRegistry	(testCtx.getArchive(), "vulkan/prebuilt")
244 	, m_library				(createLibrary(testCtx))
245 	, m_renderDoc			(testCtx.getCommandLine().isRenderDocEnabled()
246 							 ? MovePtr<vk::RenderDocUtil>(new vk::RenderDocUtil())
247 							 : MovePtr<vk::RenderDocUtil>(DE_NULL))
248 #if defined CTS_USES_VULKANSC
249 	, m_resourceInterface	(new vk::ResourceInterfaceVKSC(testCtx))
250 #else
251 	, m_resourceInterface	(new vk::ResourceInterfaceStandard(testCtx))
252 #endif // CTS_USES_VULKANSC
253 	, m_instance			(DE_NULL)
254 #if defined CTS_USES_VULKANSC
255 	, m_subprocessCount		(0)
256 #endif // CTS_USES_VULKANSC
257 {
258 #ifdef CTS_USES_VULKANSC
259 	std::vector<int> caseFraction = testCtx.getCommandLine().getCaseFraction();
260 	std::string jsonFileName;
261 	int portOffset;
262 	if (caseFraction.empty())
263 	{
264 		jsonFileName	= "pipeline_data.txt";
265 		portOffset		= 0;
266 	}
267 	else
268 	{
269 		jsonFileName	= "pipeline_data_" + std::to_string(caseFraction[0]) + ".txt";
270 		portOffset		= caseFraction[0];
271 	}
272 
273 	if (testCtx.getCommandLine().isSubProcess())
274 	{
275 		std::vector<deUint8> input = vksc_server::ipc::Child{portOffset}.GetFile(jsonFileName);
276 		m_resourceInterface->importData(input);
277 	}
278 	else
279 	{
280 		m_parentIPC.reset( new vksc_server::ipc::Parent{portOffset} );
281 	}
282 
283 	// Load information about test tree branches that use subprocess test count other than default
284 	// Expected file format:
285 	if (!testCtx.getCommandLine().isSubProcess() && !std::string(testCtx.getCommandLine().getSubprocessConfigFile()).empty())
286 	{
287 		std::ifstream			iFile(testCtx.getCommandLine().getSubprocessConfigFile(), std::ios::in);
288 		if (!iFile)
289 			TCU_THROW(InternalError, (std::string("Missing config file defining number of tests: ") + testCtx.getCommandLine().getSubprocessConfigFile()).c_str());
290 		std::string line;
291 		while (std::getline(iFile, line))
292 		{
293 			if (line.empty())
294 				continue;
295 			std::size_t pos = line.find_first_of(',');
296 			if (pos == std::string::npos)
297 				continue;
298 			std::string testPattern, testNumber;
299 			std::copy(line.begin(), line.begin() + pos, std::back_inserter(testPattern));
300 			testPattern = trim(testPattern);
301 			std::copy(line.begin() + pos + 1, line.end(), std::back_inserter(testNumber));
302 			testNumber = trim(testNumber);
303 			if (testPattern.empty() || testNumber.empty())
304 				continue;
305 			std::istringstream is(testNumber);
306 			int testCount;
307 			if ((is >> testCount).fail())
308 				continue;
309 			m_detailedSubprocessTestCount.push_back(DetailedSubprocessTestCount{ testPattern, testCount });
310 		}
311 		// sort test patterns
312 		std::sort(m_detailedSubprocessTestCount.begin(), m_detailedSubprocessTestCount.end(), [](const DetailedSubprocessTestCount& lhs, const DetailedSubprocessTestCount& rhs)
313 			{
314 				return lhs.testCount < rhs.testCount;
315 			} );
316 	}
317 
318 	// If we are provided with remote location
319 	if (!std::string(testCtx.getCommandLine().getServerAddress()).empty())
320 	{
321 		// Open connection with the server dedicated for standard output
322 		vksc_server::OpenRemoteStandardOutput(testCtx.getCommandLine().getServerAddress());
323 		restoreStandardOutput();
324 	}
325 #endif // CTS_USES_VULKANSC
326 
327 	m_context			= MovePtr<Context>(new Context(testCtx, m_library->getPlatformInterface(), m_progCollection, m_resourceInterface));
328 	m_deviceProperties	= getPhysicalDeviceProperties(*m_context);
329 
330 	tcu::SessionInfo sessionInfo(m_deviceProperties.vendorID,
331 								 m_deviceProperties.deviceID,
332 								 m_deviceProperties.deviceName,
333 								 testCtx.getCommandLine().getInitialCmdLine());
334 	m_waiverMechanism.setup(testCtx.getCommandLine().getWaiverFileName(),
335 							"dEQP-VK",
336 							m_deviceProperties.vendorID,
337 							m_deviceProperties.deviceID,
338 							sessionInfo);
339 
340 #ifdef CTS_USES_VULKANSC
341 	if (!std::string(testCtx.getCommandLine().getServerAddress()).empty())
342 	{
343 		vksc_server::AppendRequest request;
344 		request.fileName = testCtx.getCommandLine().getLogFileName();
345 
346 		std::ostringstream str;
347 		str << "#sessionInfo releaseName " << qpGetReleaseName() << std::endl;
348 		str << "#sessionInfo releaseId 0x" << std::hex << std::setw(8) << std::setfill('0') << qpGetReleaseId() << std::endl;
349 		str << "#sessionInfo targetName \"" << qpGetTargetName() << "\"" << std::endl;
350 		str << sessionInfo.get() << std::endl;
351 		str << "#beginSession" << std::endl;
352 
353 		std::string output = str.str();
354 		request.data.assign(output.begin(), output.end());
355 		request.clear = true;
356 		vksc_server::StandardOutputServerSingleton()->SendRequest(request);
357 	}
358 	else
359 #endif // CTS_USES_VULKANSC
360 	{
361 		testCtx.getLog().writeSessionInfo(sessionInfo.get());
362 	}
363 
364 #ifdef CTS_USES_VULKANSC
365 	m_resourceInterface->initApiVersion(m_context->getUsedApiVersion());
366 
367 	// Real Vulkan SC tests are performed in subprocess.
368 	// Tests run in main process are only used to collect data required by Vulkan SC.
369 	// That's why we turn off any output in main process and copy output from subprocess when subprocess tests are performed
370 	if (!testCtx.getCommandLine().isSubProcess())
371 	{
372 		suppressStandardOutput();
373 		m_context->getTestContext().getLog().supressLogging(true);
374 	}
375 #endif // CTS_USES_VULKANSC
376 }
377 
~TestCaseExecutor(void)378 TestCaseExecutor::~TestCaseExecutor (void)
379 {
380 	delete m_instance;
381 }
382 
init(tcu::TestCase * testCase,const std::string & casePath)383 void TestCaseExecutor::init (tcu::TestCase* testCase, const std::string& casePath)
384 {
385 	if (m_waiverMechanism.isOnWaiverList(casePath))
386 		throw tcu::TestException("Waived test", QP_TEST_RESULT_WAIVER);
387 
388 	TestCase*					vktCase						= dynamic_cast<TestCase*>(testCase);
389 	tcu::TestLog&				log							= m_context->getTestContext().getLog();
390 	const deUint32				usedVulkanVersion			= m_context->getUsedApiVersion();
391 	const vk::SpirvVersion		baselineSpirvVersion		= vk::getBaselineSpirvVersion(usedVulkanVersion);
392 	vk::ShaderBuildOptions		defaultGlslBuildOptions		(usedVulkanVersion, baselineSpirvVersion, 0u);
393 	vk::ShaderBuildOptions		defaultHlslBuildOptions		(usedVulkanVersion, baselineSpirvVersion, 0u);
394 	vk::SpirVAsmBuildOptions	defaultSpirvAsmBuildOptions	(usedVulkanVersion, baselineSpirvVersion);
395 	vk::SourceCollections		sourceProgs					(usedVulkanVersion, defaultGlslBuildOptions, defaultHlslBuildOptions, defaultSpirvAsmBuildOptions);
396 	const tcu::CommandLine&		commandLine					= m_context->getTestContext().getCommandLine();
397 	const bool					doShaderLog					= commandLine.isLogDecompiledSpirvEnabled() && log.isShaderLoggingEnabled();
398 
399 	if (!vktCase)
400 		TCU_THROW(InternalError, "Test node not an instance of vkt::TestCase");
401 
402 	{
403 #ifdef CTS_USES_VULKANSC
404 		int currentSubprocessCount = getCurrentSubprocessCount(casePath, m_context->getTestContext().getCommandLine().getSubprocessTestCount());
405 		if (m_subprocessCount && currentSubprocessCount != m_subprocessCount)
406 		{
407 			runTestsInSubprocess(m_context->getTestContext());
408 
409 			// Clean up data after performing tests in subprocess and prepare system for another batch of tests
410 			m_testsForSubprocess.clear();
411 			const vk::DeviceInterface&				vkd = m_context->getDeviceInterface();
412 			const vk::DeviceDriverSC*				dds = dynamic_cast<const vk::DeviceDriverSC*>(&vkd);
413 			if (dds == DE_NULL)
414 				TCU_THROW(InternalError, "Undefined device driver for Vulkan SC");
415 			dds->reset();
416 			m_resourceInterface->resetObjects();
417 
418 			suppressStandardOutput();
419 			m_context->getTestContext().getLog().supressLogging(true);
420 		}
421 		m_subprocessCount = currentSubprocessCount;
422 #endif // CTS_USES_VULKANSC
423 		m_testsForSubprocess.push_back(casePath);
424 	}
425 
426 	m_resourceInterface->initTestCase(casePath);
427 
428 	if (m_waiverMechanism.isOnWaiverList(casePath))
429 		throw tcu::TestException("Waived test", QP_TEST_RESULT_WAIVER);
430 
431 	vktCase->checkSupport(*m_context);
432 
433 	vktCase->delayedInit();
434 
435 	m_progCollection.clear();
436 	vktCase->initPrograms(sourceProgs);
437 
438 	for (vk::GlslSourceCollection::Iterator progIter = sourceProgs.glslSources.begin(); progIter != sourceProgs.glslSources.end(); ++progIter)
439 	{
440 		if (!spirvVersionSupported(progIter.getProgram().buildOptions.targetVersion))
441 			TCU_THROW(NotSupportedError, "Shader requires SPIR-V higher than available");
442 
443 		const vk::ProgramBinary* const binProg = m_resourceInterface->buildProgram<glu::ShaderProgramInfo, vk::GlslSourceCollection::Iterator>(casePath, progIter, m_prebuiltBinRegistry, &m_progCollection);
444 
445 		if (doShaderLog)
446 		{
447 			try
448 			{
449 				std::ostringstream disasm;
450 
451 				vk::disassembleProgram(*binProg, &disasm);
452 
453 				log << vk::SpirVAsmSource(disasm.str());
454 			}
455 			catch (const tcu::NotSupportedError& err)
456 			{
457 				log << err;
458 			}
459 		}
460 	}
461 
462 	for (vk::HlslSourceCollection::Iterator progIter = sourceProgs.hlslSources.begin(); progIter != sourceProgs.hlslSources.end(); ++progIter)
463 	{
464 		if (!spirvVersionSupported(progIter.getProgram().buildOptions.targetVersion))
465 			TCU_THROW(NotSupportedError, "Shader requires SPIR-V higher than available");
466 
467 		const vk::ProgramBinary* const binProg = m_resourceInterface->buildProgram<glu::ShaderProgramInfo, vk::HlslSourceCollection::Iterator>(casePath, progIter, m_prebuiltBinRegistry, &m_progCollection);
468 
469 		if (doShaderLog)
470 		{
471 			try
472 			{
473 				std::ostringstream disasm;
474 
475 				vk::disassembleProgram(*binProg, &disasm);
476 
477 				log << vk::SpirVAsmSource(disasm.str());
478 			}
479 			catch (const tcu::NotSupportedError& err)
480 			{
481 				log << err;
482 			}
483 		}
484 	}
485 
486 	for (vk::SpirVAsmCollection::Iterator asmIterator = sourceProgs.spirvAsmSources.begin(); asmIterator != sourceProgs.spirvAsmSources.end(); ++asmIterator)
487 	{
488 		if (!spirvVersionSupported(asmIterator.getProgram().buildOptions.targetVersion))
489 			TCU_THROW(NotSupportedError, "Shader requires SPIR-V higher than available");
490 
491 		m_resourceInterface->buildProgram<vk::SpirVProgramInfo, vk::SpirVAsmCollection::Iterator>(casePath, asmIterator, m_prebuiltBinRegistry, &m_progCollection);
492 	}
493 
494 	if (m_renderDoc) m_renderDoc->startFrame(m_context->getInstance());
495 
496 	DE_ASSERT(!m_instance);
497 	m_instance = vktCase->createInstance(*m_context);
498 	m_context->resultSetOnValidation(false);
499 }
500 
deinit(tcu::TestCase * testCase)501 void TestCaseExecutor::deinit (tcu::TestCase* testCase)
502 {
503 	delete m_instance;
504 	m_instance = DE_NULL;
505 
506 	if (m_renderDoc) m_renderDoc->endFrame(m_context->getInstance());
507 
508 	// Collect and report any debug messages
509 #ifndef CTS_USES_VULKANSC
510 	if (m_context->hasDebugReportRecorder())
511 		collectAndReportDebugMessages(m_context->getDebugReportRecorder(), *m_context);
512 #endif // CTS_USES_VULKANSC
513 
514 	if (testCase != DE_NULL)
515 		logUnusedShaders(testCase);
516 
517 #ifdef CTS_USES_VULKANSC
518 	if (!m_context->getTestContext().getCommandLine().isSubProcess())
519 	{
520 		int currentSubprocessCount = getCurrentSubprocessCount(m_context->getResourceInterface()->getCasePath(), m_context->getTestContext().getCommandLine().getSubprocessTestCount());
521 		if (m_testsForSubprocess.size() >= std::size_t(currentSubprocessCount))
522 		{
523 			runTestsInSubprocess(m_context->getTestContext());
524 
525 			// Clean up data after performing tests in subprocess and prepare system for another batch of tests
526 			m_testsForSubprocess.clear();
527 			const vk::DeviceInterface&				vkd						= m_context->getDeviceInterface();
528 			const vk::DeviceDriverSC*				dds						= dynamic_cast<const vk::DeviceDriverSC*>(&vkd);
529 			if (dds == DE_NULL)
530 				TCU_THROW(InternalError, "Undefined device driver for Vulkan SC");
531 			dds->reset();
532 			m_resourceInterface->resetObjects();
533 
534 			suppressStandardOutput();
535 			m_context->getTestContext().getLog().supressLogging(true);
536 		}
537 	}
538 	else
539 	{
540 		bool faultFail = false;
541 		std::lock_guard<std::mutex> lock(Context::m_faultDataMutex);
542 
543 		if (Context::m_faultData.size() != 0)
544 		{
545 			for (uint32_t i = 0; i < Context::m_faultData.size(); ++i)
546 			{
547 				m_context->getTestContext().getLog() << TestLog::Message << "Fault recorded via fault callback: " << Context::m_faultData[i] << TestLog::EndMessage;
548 				if (Context::m_faultData[i].faultLevel != VK_FAULT_LEVEL_WARNING)
549 					faultFail = true;
550 			}
551 			Context::m_faultData.clear();
552 		}
553 
554 		const vk::DeviceInterface&				vkd						= m_context->getDeviceInterface();
555 		VkBool32 unrecordedFaults = VK_FALSE;
556 		uint32_t faultCount = 0;
557 		VkResult result = vkd.getFaultData(m_context->getDevice(), VK_FAULT_QUERY_BEHAVIOR_GET_AND_CLEAR_ALL_FAULTS, &unrecordedFaults, &faultCount, DE_NULL);
558 		if (result != VK_SUCCESS)
559 		{
560 			m_context->getTestContext().getLog() << TestLog::Message << "vkGetFaultData returned error: " << getResultName(result) << TestLog::EndMessage;
561 			faultFail = true;
562 		}
563 		if (faultCount != 0)
564 		{
565 			std::vector<VkFaultData> faultData(faultCount);
566 			for (uint32_t i = 0; i < faultCount; ++i)
567 			{
568 				faultData[i] = {};
569 				faultData[i].sType = VK_STRUCTURE_TYPE_FAULT_DATA;
570 			}
571 			result = vkd.getFaultData(m_context->getDevice(), VK_FAULT_QUERY_BEHAVIOR_GET_AND_CLEAR_ALL_FAULTS, &unrecordedFaults, &faultCount, faultData.data());
572 			if (result != VK_SUCCESS)
573 			{
574 				m_context->getTestContext().getLog() << TestLog::Message << "vkGetFaultData returned error: " << getResultName(result) << TestLog::EndMessage;
575 				faultFail = true;
576 			}
577 			for (uint32_t i = 0; i < faultCount; ++i)
578 			{
579 				m_context->getTestContext().getLog() << TestLog::Message << "Fault recorded via vkGetFaultData: " << faultData[i] << TestLog::EndMessage;
580 				if (Context::m_faultData[i].faultLevel != VK_FAULT_LEVEL_WARNING)
581 					faultFail = true;
582 			}
583 		}
584 		if (faultFail)
585 			m_context->getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fault occurred");
586 	}
587 #endif // CTS_USES_VULKANSC
588 }
589 
logUnusedShaders(tcu::TestCase * testCase)590 void TestCaseExecutor::logUnusedShaders (tcu::TestCase* testCase)
591 {
592 	const qpTestResult	testResult	= testCase->getTestContext().getTestResult();
593 
594 	if (testResult == QP_TEST_RESULT_PASS || testResult == QP_TEST_RESULT_QUALITY_WARNING || testResult == QP_TEST_RESULT_COMPATIBILITY_WARNING)
595 	{
596 		bool	unusedShaders	= false;
597 
598 		for (vk::BinaryCollection::Iterator it = m_progCollection.begin(); it != m_progCollection.end(); ++it)
599 		{
600 			if (!it.getProgram().getUsed())
601 			{
602 				unusedShaders = true;
603 
604 				break;
605 			}
606 		}
607 
608 		if (unusedShaders)
609 		{
610 			std::string message;
611 
612 			for (vk::BinaryCollection::Iterator it = m_progCollection.begin(); it != m_progCollection.end(); ++it)
613 			{
614 				if (!it.getProgram().getUsed())
615 					message += it.getName() + ",";
616 			}
617 
618 			message.resize(message.size() - 1);
619 
620 			message = std::string("Unused shaders: ") + message;
621 
622 			m_context->getTestContext().getLog() << TestLog::Message << message << TestLog::EndMessage;
623 		}
624 	}
625 }
626 
iterate(tcu::TestCase *)627 tcu::TestNode::IterateResult TestCaseExecutor::iterate (tcu::TestCase*)
628 {
629 	DE_ASSERT(m_instance);
630 
631 	const tcu::TestStatus	result	= m_instance->iterate();
632 
633 	if (result.isComplete())
634 	{
635 		// Vulkan tests shouldn't set result directly except when using a debug report messenger to catch validation errors.
636 		DE_ASSERT(m_context->getTestContext().getTestResult() == QP_TEST_RESULT_LAST || m_context->resultSetOnValidation());
637 
638 		// Override result if not set previously by a debug report messenger.
639 		if (!m_context->resultSetOnValidation())
640 			m_context->getTestContext().setTestResult(result.getCode(), result.getDescription().c_str());
641 		return tcu::TestNode::STOP;
642 	}
643 	else
644 		return tcu::TestNode::CONTINUE;
645 }
646 
deinitTestPackage(tcu::TestContext & testCtx)647 void TestCaseExecutor::deinitTestPackage (tcu::TestContext& testCtx)
648 {
649 #ifdef CTS_USES_VULKANSC
650 	if (!testCtx.getCommandLine().isSubProcess())
651 	{
652 		if (!m_testsForSubprocess.empty())
653 		{
654 			runTestsInSubprocess(testCtx);
655 
656 			// Clean up data after performing tests in subprocess and prepare system for another batch of tests
657 			m_testsForSubprocess.clear();
658 			const vk::DeviceInterface&				vkd						= m_context->getDeviceInterface();
659 			const vk::DeviceDriverSC*				dds						= dynamic_cast<const vk::DeviceDriverSC*>(&vkd);
660 			if (dds == DE_NULL)
661 				TCU_THROW(InternalError, "Undefined device driver for Vulkan SC");
662 			dds->reset();
663 			m_resourceInterface->resetObjects();
664 		}
665 
666 		// Tests are finished. Next tests ( if any ) will come from other test package and test executor
667 		restoreStandardOutput();
668 		m_context->getTestContext().getLog().supressLogging(false);
669 	}
670 	m_resourceInterface->resetPipelineCaches();
671 #else
672 	DE_UNREF(testCtx);
673 #endif // CTS_USES_VULKANSC
674 }
675 
usesLocalStatus()676 bool TestCaseExecutor::usesLocalStatus ()
677 {
678 #ifdef CTS_USES_VULKANSC
679 	return !m_context->getTestContext().getCommandLine().isSubProcess();
680 #else
681 	return false;
682 #endif
683 }
684 
updateGlobalStatus(tcu::TestRunStatus & status)685 void TestCaseExecutor::updateGlobalStatus (tcu::TestRunStatus& status)
686 {
687 	status.numExecuted					+= m_status.numExecuted;
688 	status.numPassed					+= m_status.numPassed;
689 	status.numNotSupported				+= m_status.numNotSupported;
690 	status.numWarnings					+= m_status.numWarnings;
691 	status.numWaived					+= m_status.numWaived;
692 	status.numFailed					+= m_status.numFailed;
693 	m_status.clear();
694 }
695 
reportDurations(tcu::TestContext & testCtx,const std::string & packageName,const deInt64 & duration,const std::map<std::string,deUint64> & groupsDurationTime)696 void TestCaseExecutor::reportDurations(tcu::TestContext& testCtx, const std::string& packageName, const deInt64& duration, const std::map<std::string, deUint64>& groupsDurationTime)
697 {
698 #ifdef CTS_USES_VULKANSC
699 	// Send it to server to append to its log
700 	vksc_server::AppendRequest request;
701 	request.fileName = testCtx.getCommandLine().getLogFileName();
702 
703 	std::ostringstream str;
704 
705 	str << std::endl;
706 	str << "#beginTestsCasesTime" << std::endl;
707 
708 	str << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
709 	str << "<TestsCasesTime>" << std::endl;
710 
711 	str << " <Number Name=\"" << packageName << "\" Description=\"Total tests case duration in microseconds\" Tag=\"Time\" Unit=\"us\">" << duration << "</Number>" << std::endl;
712 	for (std::map<std::string, deUint64>::const_iterator it = groupsDurationTime.begin(); it != groupsDurationTime.end(); ++it)
713 		str << " <Number Name=\"" << it->first << "\" Description=\"The test group case duration in microseconds\" Tag=\"Time\" Unit=\"us\">" << it->second << "</Number>" << std::endl;
714 	str << "</TestsCasesTime>" << std::endl;
715 	str << std::endl;
716 	str << "#endTestsCasesTime" << std::endl;
717 	str << std::endl;
718 	str << "#endSession" << std::endl;
719 
720 	std::string output = str.str();
721 	request.data.assign(output.begin(), output.end());
722 	vksc_server::StandardOutputServerSingleton()->SendRequest(request);
723 #else
724 	DE_UNREF(testCtx);
725 	DE_UNREF(packageName);
726 	DE_UNREF(duration);
727 	DE_UNREF(groupsDurationTime);
728 #endif // CTS_USES_VULKANSC
729 
730 }
731 
getCurrentSubprocessCount(const std::string & casePath,int defaultSubprocessCount)732 int TestCaseExecutor::getCurrentSubprocessCount(const std::string& casePath, int defaultSubprocessCount)
733 {
734 #ifdef CTS_USES_VULKANSC
735 	for (const auto& detailed : m_detailedSubprocessTestCount)
736 		if (tcu::matchWildcards(detailed.testPattern.begin(), detailed.testPattern.end(), casePath.begin(), casePath.end(), false))
737 			return detailed.testCount;
738 #else
739 	DE_UNREF(casePath);
740 #endif // CTS_USES_VULKANSC
741 	return defaultSubprocessCount;
742 }
743 
runTestsInSubprocess(tcu::TestContext & testCtx)744 void TestCaseExecutor::runTestsInSubprocess (tcu::TestContext& testCtx)
745 {
746 #ifdef CTS_USES_VULKANSC
747 	if (testCtx.getCommandLine().isSubProcess())
748 		TCU_THROW(InternalError, "Cannot run subprocess inside subprocess : ");
749 
750 	if (m_testsForSubprocess.empty())
751 		return;
752 
753 	std::vector<int>	caseFraction	= testCtx.getCommandLine().getCaseFraction();
754 	std::ostringstream	jsonFileName, qpaFileName, pipelineCompilerOutFileName, pipelineCompilerLogFileName, pipelineCompilerPrefix;
755 	if (caseFraction.empty())
756 	{
757 		jsonFileName				<< "pipeline_data.txt";
758 		qpaFileName					<< "sub.qpa";
759 		if (!std::string(testCtx.getCommandLine().getPipelineCompilerPath()).empty())
760 		{
761 			pipelineCompilerOutFileName << "pipeline_cache.bin";
762 			pipelineCompilerLogFileName << "compiler.log";
763 			pipelineCompilerPrefix << "";
764 		}
765 	}
766 	else
767 	{
768 		jsonFileName	<< "pipeline_data_" << caseFraction[0] << ".txt";
769 		qpaFileName		<< "sub_" << caseFraction[0] << ".qpa";
770 		if (!std::string(testCtx.getCommandLine().getPipelineCompilerPath()).empty())
771 		{
772 			pipelineCompilerOutFileName << "pipeline_cache_" << caseFraction[0] <<".bin";
773 			pipelineCompilerLogFileName << "compiler_" << caseFraction[0] << ".log";
774 			pipelineCompilerPrefix << "sub_" << caseFraction[0] << "_";
775 		}
776 	}
777 
778 	// export data collected during statistics gathering to JSON file ( VkDeviceObjectReservationCreateInfo, SPIR-V shaders, pipelines )
779 	{
780 		m_resourceInterface->removeRedundantObjects();
781 		m_resourceInterface->finalizeCommandBuffers();
782 		std::vector<deUint8>					data					= m_resourceInterface->exportData();
783 		m_parentIPC->SetFile(jsonFileName.str(), data);
784 	}
785 
786 	// collect current application name, add it to new commandline with subprocess parameters
787 	std::string								newCmdLine;
788 	{
789 		std::string appName = testCtx.getCommandLine().getApplicationName();
790 		if (appName.empty())
791 			TCU_THROW(InternalError, "Application name is not defined");
792 		// add --deqp-subprocess option to inform deqp-vksc process that it works as slave process
793 		newCmdLine = appName + " --deqp-subprocess=enable --deqp-log-filename=" + qpaFileName.str();
794 
795 		// add offline pipeline compiler parameters if present
796 		if (!std::string(testCtx.getCommandLine().getPipelineCompilerPath()).empty())
797 		{
798 			newCmdLine += " --deqp-pipeline-compiler="		+ std::string(testCtx.getCommandLine().getPipelineCompilerPath());
799 			newCmdLine += " --deqp-pipeline-file="			+ pipelineCompilerOutFileName.str();
800 			if (!std::string(testCtx.getCommandLine().getPipelineCompilerDataDir()).empty())
801 				newCmdLine += " --deqp-pipeline-dir="			+ std::string(testCtx.getCommandLine().getPipelineCompilerDataDir());
802 			newCmdLine += " --deqp-pipeline-logfile="		+ pipelineCompilerLogFileName.str();
803 			if(!pipelineCompilerPrefix.str().empty())
804 				newCmdLine += " --deqp-pipeline-prefix="	+ pipelineCompilerPrefix.str();
805 			if (!std::string(testCtx.getCommandLine().getPipelineCompilerArgs()).empty())
806 				newCmdLine += " --deqp-pipeline-args=\""	+ std::string( testCtx.getCommandLine().getPipelineCompilerArgs() ) + "\"";
807 		}
808 	}
809 
810 	// collect parameters, remove parameters associated with case filter and case fraction. We will provide our own case list
811 	{
812 		std::string							originalCmdLine		= testCtx.getCommandLine().getInitialCmdLine();
813 
814 		// brave ( but working ) assumption that each CTS parameter starts with "--deqp"
815 
816 		std::string							paramStr			("--deqp");
817 		std::vector<std::string>			skipElements		=
818 		{
819 			"--deqp-case",
820 			"--deqp-stdin-caselist",
821 			"--deqp-log-filename",
822 			"--deqp-pipeline-compiler",
823 			"--deqp-pipeline-dir",
824 			"--deqp-pipeline-args",
825 			"--deqp-pipeline-file",
826 			"--deqp-pipeline-logfile",
827 			"--deqp-pipeline-prefix"
828 		};
829 
830 		std::size_t							pos = 0;
831 		std::vector<std::size_t>			argPos;
832 		while ((pos = originalCmdLine.find(paramStr, pos)) != std::string::npos)
833 			argPos.push_back(pos++);
834 		if (!argPos.empty())
835 			argPos.push_back(originalCmdLine.size());
836 
837 		std::vector<std::string> args;
838 		for (std::size_t i = 0; i < argPos.size()-1; ++i)
839 		{
840 			std::string s = originalCmdLine.substr(argPos[i], argPos[i + 1] - argPos[i]);
841 			std::size_t found = s.find_last_not_of(' ');
842 			if (found != std::string::npos)
843 			{
844 				s.erase(found + 1);
845 				args.push_back(s);
846 			}
847 		}
848 		for (std::size_t i = 0; i < args.size(); ++i)
849 		{
850 			bool skipElement = false;
851 			for (const auto& elem : skipElements)
852 				if (args[i].find(elem) == 0)
853 				{
854 					skipElement = true;
855 					break;
856 				}
857 			if (skipElement)
858 				continue;
859 			newCmdLine = newCmdLine + " " + args[i];
860 		}
861 	}
862 
863 	// create --deqp-case list from tests collected in m_testsForSubprocess
864 	std::string subprocessTestList;
865 	for (auto it = begin(m_testsForSubprocess); it != end(m_testsForSubprocess); ++it)
866 	{
867 		auto nit = it; ++nit;
868 
869 		subprocessTestList += *it;
870 		if (nit != end(m_testsForSubprocess))
871 			subprocessTestList += "\n";
872 	}
873 
874 	std::string caseListName	= "subcaselist" + (caseFraction.empty() ? std::string("") : de::toString(caseFraction[0])) + ".txt";
875 
876 	deFile*		exportFile		= deFile_create(caseListName.c_str(), DE_FILEMODE_CREATE | DE_FILEMODE_OPEN | DE_FILEMODE_WRITE | DE_FILEMODE_TRUNCATE);
877 	deInt64		numWritten		= 0;
878 	deFile_write(exportFile, subprocessTestList.c_str(), subprocessTestList.size(), &numWritten);
879 	deFile_destroy(exportFile);
880 	newCmdLine = newCmdLine + " --deqp-caselist-file=" + caseListName;
881 
882 	// restore cout and cerr
883 	restoreStandardOutput();
884 
885 	// create subprocess which will perform real tests
886 	std::string subProcessExitCodeInfo;
887 	{
888 		deProcess*	process			= deProcess_create();
889 		if (deProcess_start(process, newCmdLine.c_str(), ".") != DE_TRUE)
890 		{
891 			std::string err = deProcess_getLastError(process);
892 			deProcess_destroy(process);
893 			process = DE_NULL;
894 			TCU_THROW(InternalError, "Error while running subprocess : " + err);
895 		}
896 		std::string whole;
897 		whole.reserve(1024 * 4);
898 
899 		// create a separate thread that captures std::err output
900 		de::MovePtr<std::thread> errThread(new std::thread([&process]
901 		{
902 			deFile*		subErr = deProcess_getStdErr(process);
903 			char		errBuffer[128]	= { 0 };
904 			deInt64		errNumRead		= 0;
905 			while (deFile_read(subErr, errBuffer, sizeof(errBuffer) - 1, &errNumRead) == DE_FILERESULT_SUCCESS)
906 			{
907 				errBuffer[errNumRead] = 0;
908 			}
909 		}));
910 
911 		deFile*		subOutput		= deProcess_getStdOut(process);
912 		char		outBuffer[128]	= { 0 };
913 		deInt64		numRead			= 0;
914 		while (deFile_read(subOutput, outBuffer, sizeof(outBuffer) - 1, &numRead) == DE_FILERESULT_SUCCESS)
915 		{
916 			outBuffer[numRead] = 0;
917 			qpPrint(outBuffer);
918 			whole += outBuffer;
919 		}
920 		errThread->join();
921 		if (deProcess_waitForFinish(process))
922 		{
923 			const int			exitCode = deProcess_getExitCode(process);
924 			std::stringstream	s;
925 
926 			s << " Subprocess failed with exit code " << exitCode << "(" << std::hex << exitCode << ")";
927 
928 			subProcessExitCodeInfo = s.str();
929 		}
930 		deProcess_destroy(process);
931 
932 		vksc_server::RemoteWrite(0, whole.c_str());
933 	}
934 
935 	// copy test information from sub.qpa to main log
936 	{
937 		std::ifstream	subQpa(qpaFileName.str(), std::ios::binary);
938 		std::string		subQpaText{std::istreambuf_iterator<char>(subQpa),
939 								   std::istreambuf_iterator<char>()};
940 		{
941 			std::string			beginText		("#beginTestCaseResult");
942 			std::string			endText			("#endTestCaseResult");
943 			std::size_t			beginPos		= subQpaText.find(beginText);
944 			std::size_t			endPos			= subQpaText.rfind(endText);
945 			if (beginPos == std::string::npos || endPos == std::string::npos)
946 				TCU_THROW(InternalError, "Couldn't match tags from " + qpaFileName.str() + subProcessExitCodeInfo);
947 
948 			std::string		subQpaCopy = "\n" + std::string(subQpaText.begin() + beginPos, subQpaText.begin() + endPos + endText.size()) + "\n";
949 
950 			if (!std::string(testCtx.getCommandLine().getServerAddress()).empty())
951 			{
952 				// Send it to server to append to its log
953 				vksc_server::AppendRequest request;
954 				request.fileName = testCtx.getCommandLine().getLogFileName();
955 				request.data.assign(subQpaCopy.begin(), subQpaCopy.end());
956 				vksc_server::StandardOutputServerSingleton()->SendRequest(request);
957 			}
958 			else
959 			{
960 				// Write it to parent's log
961 				try
962 				{
963 					testCtx.getLog().supressLogging(false);
964 					testCtx.getLog().writeRaw(subQpaCopy.c_str());
965 				}
966 				catch(...)
967 				{
968 					testCtx.getLog().supressLogging(true);
969 					throw;
970 				}
971 				testCtx.getLog().supressLogging(true);
972 			}
973 		}
974 
975 		{
976 			std::string			beginStat		("#SubProcessStatus");
977 			std::size_t			beginPos		= subQpaText.find(beginStat);
978 			if (beginPos == std::string::npos)
979 				TCU_THROW(InternalError, "Couldn't match #SubProcessStatus tag from " + qpaFileName.str() + subProcessExitCodeInfo);
980 
981 			std::string			subQpaStat		(subQpaText.begin() + beginPos + beginStat.size(), subQpaText.end());
982 
983 			std::istringstream	str(subQpaStat);
984 			int					numExecuted, numPassed, numFailed, numNotSupported, numWarnings, numWaived;
985 			str >> numExecuted >> numPassed >> numFailed >> numNotSupported >> numWarnings >> numWaived;
986 
987 			m_status.numExecuted				+= numExecuted;
988 			m_status.numPassed					+= numPassed;
989 			m_status.numNotSupported			+= numNotSupported;
990 			m_status.numWarnings				+= numWarnings;
991 			m_status.numWaived					+= numWaived;
992 			m_status.numFailed					+= numFailed;
993 		}
994 
995 		deDeleteFile(qpaFileName.str().c_str());
996 	}
997 #else
998 	DE_UNREF(testCtx);
999 #endif // CTS_USES_VULKANSC
1000 }
1001 
spirvVersionSupported(vk::SpirvVersion spirvVersion)1002 bool TestCaseExecutor::spirvVersionSupported (vk::SpirvVersion spirvVersion)
1003 {
1004 	if (spirvVersion <= vk::getMaxSpirvVersionForVulkan(m_context->getUsedApiVersion()))
1005 		return true;
1006 
1007 	if (spirvVersion <= vk::SPIRV_VERSION_1_4)
1008 		return m_context->isDeviceFunctionalitySupported("VK_KHR_spirv_1_4");
1009 
1010 	return false;
1011 }
1012 
1013 // GLSL shader tests
1014 
createGlslTests(tcu::TestCaseGroup * glslTests)1015 void createGlslTests (tcu::TestCaseGroup* glslTests)
1016 {
1017 	tcu::TestContext&	testCtx		= glslTests->getTestContext();
1018 
1019 	// ShaderLibrary-based tests
1020 	static const struct
1021 	{
1022 		const char*		name;
1023 	} s_es310Tests[] =
1024 	{
1025 		{ "arrays"},
1026 		{ "conditionals"},
1027 		{ "constant_expressions"},
1028 		{ "constants"},
1029 		{ "conversions"},
1030 		{ "functions"},
1031 		{ "linkage"},
1032 		{ "scoping"},
1033 		{ "swizzles"},
1034 	};
1035 
1036 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_es310Tests); ndx++)
1037 		glslTests->addChild(createShaderLibraryGroup(testCtx,
1038 													 s_es310Tests[ndx].name,
1039 													 std::string("vulkan/glsl/es310/") + s_es310Tests[ndx].name + ".test").release());
1040 
1041 	static const struct
1042 	{
1043 		const char*		name;
1044 	} s_440Tests[] =
1045 	{
1046 		{ "linkage"},
1047 	};
1048 
1049 	de::MovePtr<tcu::TestCaseGroup> glsl440Tests = de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "440"));
1050 
1051 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_440Tests); ndx++)
1052 		glsl440Tests->addChild(createShaderLibraryGroup(testCtx,
1053 													 s_440Tests[ndx].name,
1054 													 std::string("vulkan/glsl/440/") + s_440Tests[ndx].name + ".test").release());
1055 
1056 	glslTests->addChild(glsl440Tests.release());
1057 
1058 	// ShaderRenderCase-based tests
1059 	glslTests->addChild(sr::createDerivateTests			(testCtx));
1060 	glslTests->addChild(sr::createDiscardTests			(testCtx));
1061 #ifndef CTS_USES_VULKANSC
1062 	glslTests->addChild(sr::createDemoteTests			(testCtx));
1063 #endif // CTS_USES_VULKANSC
1064 	glslTests->addChild(sr::createIndexingTests			(testCtx));
1065 	glslTests->addChild(sr::createShaderInvarianceTests	(testCtx));
1066 	glslTests->addChild(sr::createLimitTests			(testCtx));
1067 	glslTests->addChild(sr::createLoopTests				(testCtx));
1068 	glslTests->addChild(sr::createMatrixTests			(testCtx));
1069 	glslTests->addChild(sr::createOperatorTests			(testCtx));
1070 	glslTests->addChild(sr::createReturnTests			(testCtx));
1071 	glslTests->addChild(sr::createStructTests			(testCtx));
1072 	glslTests->addChild(sr::createSwitchTests			(testCtx));
1073 	glslTests->addChild(sr::createTextureFunctionTests	(testCtx));
1074 	glslTests->addChild(sr::createTextureGatherTests	(testCtx));
1075 	glslTests->addChild(sr::createBuiltinVarTests		(testCtx));
1076 
1077 	// ShaderExecutor-based tests
1078 	glslTests->addChild(shaderexecutor::createBuiltinTests				(testCtx));
1079 	glslTests->addChild(shaderexecutor::createOpaqueTypeIndexingTests	(testCtx));
1080 	glslTests->addChild(shaderexecutor::createAtomicOperationTests		(testCtx));
1081 	glslTests->addChild(shaderexecutor::createShaderClockTests			(testCtx));
1082 
1083 #ifndef CTS_USES_VULKANSC
1084 	// Amber GLSL tests.
1085 	glslTests->addChild(cts_amber::createCombinedOperationsGroup		(testCtx));
1086 	glslTests->addChild(cts_amber::createCrashTestGroup					(testCtx));
1087 #endif // CTS_USES_VULKANSC
1088 }
1089 
1090 // TestPackage
1091 
BaseTestPackage(tcu::TestContext & testCtx,const char * name)1092 BaseTestPackage::BaseTestPackage (tcu::TestContext& testCtx, const char* name)
1093 	: tcu::TestPackage(testCtx, name, "")
1094 {
1095 }
1096 
~BaseTestPackage(void)1097 BaseTestPackage::~BaseTestPackage (void)
1098 {
1099 }
1100 
1101 #ifdef CTS_USES_VULKAN
1102 
TestPackage(tcu::TestContext & testCtx)1103 TestPackage::TestPackage (tcu::TestContext& testCtx)
1104 	: BaseTestPackage(testCtx, "dEQP-VK")
1105 {
1106 }
1107 
~TestPackage(void)1108 TestPackage::~TestPackage (void)
1109 {
1110 }
1111 
ExperimentalTestPackage(tcu::TestContext & testCtx)1112 ExperimentalTestPackage::ExperimentalTestPackage (tcu::TestContext& testCtx)
1113 	: BaseTestPackage(testCtx, "dEQP-VK-experimental")
1114 {
1115 }
1116 
~ExperimentalTestPackage(void)1117 ExperimentalTestPackage::~ExperimentalTestPackage (void)
1118 {
1119 }
1120 
1121 #endif
1122 
1123 #ifdef CTS_USES_VULKANSC
1124 
TestPackageSC(tcu::TestContext & testCtx)1125 TestPackageSC::TestPackageSC (tcu::TestContext& testCtx)
1126 	: BaseTestPackage(testCtx, "dEQP-VKSC")
1127 {
1128 }
1129 
~TestPackageSC(void)1130 TestPackageSC::~TestPackageSC (void)
1131 {
1132 }
1133 
1134 #endif // CTS_USES_VULKANSC
1135 
createExecutor(void) const1136 tcu::TestCaseExecutor* BaseTestPackage::createExecutor (void) const
1137 {
1138 	return new TestCaseExecutor(m_testCtx);
1139 }
1140 
createGlslTests(tcu::TestContext & testCtx,const std::string & name)1141 tcu::TestCaseGroup* createGlslTests (tcu::TestContext& testCtx, const std::string& name)
1142 {
1143 	return createTestGroup(testCtx, name, createGlslTests);
1144 }
1145 
1146 #ifdef CTS_USES_VULKAN
1147 
init(void)1148 void TestPackage::init (void)
1149 {
1150 	addRootChild("info", m_caseListFilter,							info::createTests);
1151 	addRootChild("api", m_caseListFilter,							api::createTests);
1152 	addRootChild("memory", m_caseListFilter,						memory::createTests);
1153 	addRootChild("pipeline", m_caseListFilter,						pipeline::createTests);
1154 	addRootChild("binding_model", m_caseListFilter,					BindingModel::createTests);
1155 	addRootChild("spirv_assembly", m_caseListFilter,				SpirVAssembly::createTests);
1156 	addRootChild("glsl", m_caseListFilter,							createGlslTests);
1157 	addRootChild("renderpass", m_caseListFilter,					createRenderPassTests);
1158 	addRootChild("renderpass2", m_caseListFilter,					createRenderPass2Tests);
1159 	addRootChild("dynamic_rendering", m_caseListFilter,				createDynamicRenderingTests);
1160 	addRootChild("ubo", m_caseListFilter,							ubo::createTests);
1161 	addRootChild("dynamic_state", m_caseListFilter,					DynamicState::createTests);
1162 	addRootChild("ssbo", m_caseListFilter,							ssbo::createTests);
1163 	addRootChild("query_pool", m_caseListFilter,					QueryPool::createTests);
1164 	addRootChild("draw", m_caseListFilter,							Draw::createTests);
1165 	addRootChild("compute", m_caseListFilter,						compute::createTests);
1166 	addRootChild("image", m_caseListFilter,							image::createTests);
1167 	addRootChild("wsi", m_caseListFilter,							wsi::createTests);
1168 	addRootChild("synchronization", m_caseListFilter,				createSynchronizationTests);
1169 	addRootChild("synchronization2", m_caseListFilter,				createSynchronization2Tests);
1170 	addRootChild("sparse_resources", m_caseListFilter,				sparse::createTests);
1171 	addRootChild("tessellation", m_caseListFilter,					tessellation::createTests);
1172 	addRootChild("rasterization", m_caseListFilter,					rasterization::createTests);
1173 	addRootChild("clipping", m_caseListFilter,						clipping::createTests);
1174 	addRootChild("fragment_operations", m_caseListFilter,			FragmentOperations::createTests);
1175 	addRootChild("texture", m_caseListFilter,						texture::createTests);
1176 	addRootChild("geometry", m_caseListFilter,						geometry::createTests);
1177 	addRootChild("robustness", m_caseListFilter,					robustness::createTests);
1178 	addRootChild("multiview", m_caseListFilter,						MultiView::createTests);
1179 	addRootChild("subgroups", m_caseListFilter,						subgroups::createTests);
1180 	addRootChild("ycbcr", m_caseListFilter,							ycbcr::createTests);
1181 	addRootChild("protected_memory", m_caseListFilter,				ProtectedMem::createTests);
1182 	addRootChild("device_group", m_caseListFilter,					DeviceGroup::createTests);
1183 	addRootChild("memory_model", m_caseListFilter,					MemoryModel::createTests);
1184 	addRootChild("conditional_rendering", m_caseListFilter,			conditional::createTests);
1185 	addRootChild("graphicsfuzz", m_caseListFilter,					cts_amber::createGraphicsFuzzTests);
1186 	addRootChild("imageless_framebuffer", m_caseListFilter,			imageless::createTests);
1187 	addRootChild("transform_feedback", m_caseListFilter,			TransformFeedback::createTests);
1188 	addRootChild("descriptor_indexing", m_caseListFilter,			DescriptorIndexing::createTests);
1189 	addRootChild("fragment_shader_interlock", m_caseListFilter,		FragmentShaderInterlock::createTests);
1190 	addRootChild("drm_format_modifiers", m_caseListFilter,			modifiers::createTests);
1191 	addRootChild("ray_tracing_pipeline", m_caseListFilter,			RayTracing::createTests);
1192 	addRootChild("ray_query", m_caseListFilter,						RayQuery::createTests);
1193 	addRootChild("fragment_shading_rate", m_caseListFilter,			FragmentShadingRate::createTests);
1194 	addRootChild("reconvergence", m_caseListFilter,					Reconvergence::createTests);
1195 	addRootChild("mesh_shader", m_caseListFilter,					MeshShader::createTests);
1196 	addRootChild("fragment_shading_barycentric", m_caseListFilter,	FragmentShadingBarycentric::createTests);
1197 	// Amber depth pipeline tests
1198 	addRootChild("depth", m_caseListFilter,							cts_amber::createAmberDepthGroup);
1199 #ifndef DEQP_EXCLUDE_VK_VIDEO_TESTS
1200 	//addRootChild("video", m_caseListFilter,							video::createTests);
1201 #endif
1202 	addRootChild("shader_object", m_caseListFilter,					ShaderObject::createTests);
1203 }
1204 
init(void)1205 void ExperimentalTestPackage::init (void)
1206 {
1207 	addRootChild("postmortem", m_caseListFilter,					postmortem::createTests);
1208 	addRootChild("reconvergence", m_caseListFilter,					Reconvergence::createTestsExperimental);
1209 }
1210 
1211 #endif
1212 
1213 #ifdef CTS_USES_VULKANSC
1214 
init(void)1215 void TestPackageSC::init (void)
1216 {
1217 	addRootChild("info", m_caseListFilter,						info::createTests);
1218 	addRootChild("api", m_caseListFilter,						api::createTests);
1219 	addRootChild("memory", m_caseListFilter,					memory::createTests);
1220 	addRootChild("pipeline", m_caseListFilter,					pipeline::createTests);
1221 	addRootChild("binding_model", m_caseListFilter,				BindingModel::createTests);
1222 	addRootChild("spirv_assembly", m_caseListFilter,			SpirVAssembly::createTests);
1223 	addRootChild("glsl", m_caseListFilter,						createGlslTests);
1224 	addRootChild("renderpass", m_caseListFilter,				createRenderPassTests);
1225 	addRootChild("renderpass2", m_caseListFilter,				createRenderPass2Tests);
1226 	addRootChild("ubo", m_caseListFilter,						ubo::createTests);
1227 	addRootChild("dynamic_state", m_caseListFilter,				DynamicState::createTests);
1228 	addRootChild("ssbo", m_caseListFilter,						ssbo::createTests);
1229 	addRootChild("query_pool", m_caseListFilter,				QueryPool::createTests);
1230 	addRootChild("draw", m_caseListFilter,						Draw::createTests);
1231 	addRootChild("compute", m_caseListFilter,					compute::createTests);
1232 	addRootChild("image", m_caseListFilter,						image::createTests);
1233 //	addRootChild("wsi", m_caseListFilter,						wsi::createTests);
1234 	addRootChild("synchronization", m_caseListFilter,			createSynchronizationTests);
1235 	addRootChild("synchronization2", m_caseListFilter,			createSynchronization2Tests);
1236 //	addRootChild("sparse_resources", m_caseListFilter,			sparse::createTests);
1237 	addRootChild("tessellation", m_caseListFilter,				tessellation::createTests);
1238 	addRootChild("rasterization", m_caseListFilter,				rasterization::createTests);
1239 	addRootChild("clipping", m_caseListFilter,					clipping::createTests);
1240 	addRootChild("fragment_operations", m_caseListFilter,		FragmentOperations::createTests);
1241 	addRootChild("texture", m_caseListFilter,					texture::createTests);
1242 	addRootChild("geometry", m_caseListFilter,					geometry::createTests);
1243 	addRootChild("robustness", m_caseListFilter,				robustness::createTests);
1244 	addRootChild("multiview", m_caseListFilter,					MultiView::createTests);
1245 	addRootChild("subgroups", m_caseListFilter,					subgroups::createTests);
1246 	addRootChild("ycbcr", m_caseListFilter,						ycbcr::createTests);
1247 	addRootChild("protected_memory", m_caseListFilter,			ProtectedMem::createTests);
1248 	addRootChild("device_group", m_caseListFilter,				DeviceGroup::createTests);
1249 	addRootChild("memory_model", m_caseListFilter,				MemoryModel::createTests);
1250 //	addRootChild("conditional_rendering", m_caseListFilter,		conditional::createTests);
1251 //	addRootChild("graphicsfuzz", m_caseListFilter,				cts_amber::createGraphicsFuzzTests);
1252 	addRootChild("imageless_framebuffer", m_caseListFilter,		imageless::createTests);
1253 //	addRootChild("transform_feedback", m_caseListFilter,		TransformFeedback::createTests);
1254 	addRootChild("descriptor_indexing", m_caseListFilter,		DescriptorIndexing::createTests);
1255 	addRootChild("fragment_shader_interlock", m_caseListFilter,	FragmentShaderInterlock::createTests);
1256 //	addRootChild("drm_format_modifiers", m_caseListFilter,		modifiers::createTests);
1257 //	addRootChild("ray_tracing_pipeline", m_caseListFilter,		RayTracing::createTests);
1258 //	addRootChild("ray_query", m_caseListFilter,					RayQuery::createTests);
1259 	addRootChild("fragment_shading_rate", m_caseListFilter,		FragmentShadingRate::createTests);
1260 	addChild(sc::createTests(m_testCtx));
1261 }
1262 
1263 #endif // CTS_USES_VULKANSC
1264 
1265 } // vkt
1266