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