a57d5a0d8e3a588a4a1371719edbc420c04f3c75
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / vktTestPackage.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Vulkan Test Package
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktTestPackage.hpp"
25
26 #include "tcuPlatform.hpp"
27 #include "tcuTestCase.hpp"
28 #include "tcuTestLog.hpp"
29 #include "tcuCommandLine.hpp"
30
31 #include "vkPlatform.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkBinaryRegistry.hpp"
34 #include "vkShaderToSpirV.hpp"
35 #include "vkDebugReportUtil.hpp"
36 #include "vkQueryUtil.hpp"
37 #include "vkApiVersion.hpp"
38
39 #include "deUniquePtr.hpp"
40
41 #include "vktTestGroupUtil.hpp"
42 #include "vktApiTests.hpp"
43 #include "vktPipelineTests.hpp"
44 #include "vktBindingModelTests.hpp"
45 #include "vktSpvAsmTests.hpp"
46 #include "vktShaderLibrary.hpp"
47 #include "vktRenderPassTests.hpp"
48 #include "vktMemoryTests.hpp"
49 #include "vktShaderRenderBuiltinVarTests.hpp"
50 #include "vktShaderRenderDerivateTests.hpp"
51 #include "vktShaderRenderDiscardTests.hpp"
52 #include "vktShaderRenderIndexingTests.hpp"
53 #include "vktShaderRenderLoopTests.hpp"
54 #include "vktShaderRenderMatrixTests.hpp"
55 #include "vktShaderRenderOperatorTests.hpp"
56 #include "vktShaderRenderReturnTests.hpp"
57 #include "vktShaderRenderStructTests.hpp"
58 #include "vktShaderRenderSwitchTests.hpp"
59 #include "vktShaderRenderTextureFunctionTests.hpp"
60 #include "vktShaderRenderTextureGatherTests.hpp"
61 #include "vktShaderBuiltinTests.hpp"
62 #include "vktOpaqueTypeIndexingTests.hpp"
63 #include "vktAtomicOperationTests.hpp"
64 #include "vktUniformBlockTests.hpp"
65 #include "vktDynamicStateTests.hpp"
66 #include "vktSSBOLayoutTests.hpp"
67 #include "vktQueryPoolTests.hpp"
68 #include "vktDrawTests.hpp"
69 #include "vktComputeTests.hpp"
70 #include "vktImageTests.hpp"
71 #include "vktInfoTests.hpp"
72 #include "vktWsiTests.hpp"
73 #include "vktSynchronizationTests.hpp"
74 #include "vktSparseResourcesTests.hpp"
75 #include "vktTessellationTests.hpp"
76 #include "vktRasterizationTests.hpp"
77 #include "vktClippingTests.hpp"
78 #include "vktFragmentOperationsTests.hpp"
79 #include "vktTextureTests.hpp"
80 #include "vktGeometryTests.hpp"
81 #include "vktRobustnessTests.hpp"
82 #include "vktMultiViewTests.hpp"
83 #include "vktSubgroupsTests.hpp"
84 #include "vktYCbCrTests.hpp"
85 #include "vktProtectedMemTests.hpp"
86
87 #include <vector>
88 #include <sstream>
89
90 namespace // compilation
91 {
92
93 vk::ProgramBinary* compileProgram (const vk::GlslSource& source, glu::ShaderProgramInfo* buildInfo)
94 {
95         return vk::buildProgram(source, buildInfo);
96 }
97
98 vk::ProgramBinary* compileProgram (const vk::HlslSource& source, glu::ShaderProgramInfo* buildInfo)
99 {
100         return vk::buildProgram(source, buildInfo);
101 }
102
103 vk::ProgramBinary* compileProgram (const vk::SpirVAsmSource& source, vk::SpirVProgramInfo* buildInfo)
104 {
105         return vk::assembleProgram(source, buildInfo);
106 }
107
108 template <typename InfoType, typename IteratorType>
109 vk::ProgramBinary* buildProgram (const std::string&                                     casePath,
110                                                                  IteratorType                                           iter,
111                                                                  const vk::BinaryRegistryReader&        prebuiltBinRegistry,
112                                                                  tcu::TestLog&                                          log,
113                                                                  vk::BinaryCollection*                          progCollection)
114 {
115         const vk::ProgramIdentifier             progId          (casePath, iter.getName());
116         const tcu::ScopedLogSection             progSection     (log, iter.getName(), "Program: " + iter.getName());
117         de::MovePtr<vk::ProgramBinary>  binProg;
118         InfoType                                                buildInfo;
119
120         try
121         {
122                 binProg = de::MovePtr<vk::ProgramBinary>(compileProgram(iter.getProgram(), &buildInfo));
123                 log << buildInfo;
124         }
125         catch (const tcu::NotSupportedError& err)
126         {
127                 // Try to load from cache
128                 log << err << tcu::TestLog::Message << "Building from source not supported, loading stored binary instead" << tcu::TestLog::EndMessage;
129
130                 binProg = de::MovePtr<vk::ProgramBinary>(prebuiltBinRegistry.loadProgram(progId));
131
132                 log << iter.getProgram();
133         }
134         catch (const tcu::Exception&)
135         {
136                 // Build failed for other reason
137                 log << buildInfo;
138                 throw;
139         }
140
141         TCU_CHECK_INTERNAL(binProg);
142
143         {
144                 vk::ProgramBinary* const        returnBinary    = binProg.get();
145
146                 progCollection->add(progId.programName, binProg);
147
148                 return returnBinary;
149         }
150 }
151
152 } // anonymous(compilation)
153
154 namespace vkt
155 {
156
157 using std::vector;
158 using de::UniquePtr;
159 using de::MovePtr;
160 using tcu::TestLog;
161
162 namespace
163 {
164
165 MovePtr<vk::DebugReportRecorder> createDebugReportRecorder (const vk::PlatformInterface& vkp, const vk::InstanceInterface& vki, vk::VkInstance instance)
166 {
167         if (isDebugReportSupported(vkp))
168                 return MovePtr<vk::DebugReportRecorder>(new vk::DebugReportRecorder(vki, instance));
169         else
170                 TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
171 }
172
173 } // anonymous
174
175 // TestCaseExecutor
176
177 class TestCaseExecutor : public tcu::TestCaseExecutor
178 {
179 public:
180                                                                                                 TestCaseExecutor        (tcu::TestContext& testCtx);
181                                                                                                 ~TestCaseExecutor       (void);
182
183         virtual void                                                            init                            (tcu::TestCase* testCase, const std::string& path);
184         virtual void                                                            deinit                          (tcu::TestCase* testCase);
185
186         virtual tcu::TestNode::IterateResult            iterate                         (tcu::TestCase* testCase);
187
188 private:
189         vk::BinaryCollection                                            m_progCollection;
190         vk::BinaryRegistryReader                                        m_prebuiltBinRegistry;
191
192         const UniquePtr<vk::Library>                            m_library;
193         Context                                                                         m_context;
194
195         const UniquePtr<vk::DebugReportRecorder>        m_debugReportRecorder;
196
197         TestInstance*                                                           m_instance;                     //!< Current test case instance
198 };
199
200 static MovePtr<vk::Library> createLibrary (tcu::TestContext& testCtx)
201 {
202         return MovePtr<vk::Library>(testCtx.getPlatform().getVulkanPlatform().createLibrary());
203 }
204
205 TestCaseExecutor::TestCaseExecutor (tcu::TestContext& testCtx)
206         : m_prebuiltBinRegistry (testCtx.getArchive(), "vulkan/prebuilt")
207         , m_library                             (createLibrary(testCtx))
208         , m_context                             (testCtx, m_library->getPlatformInterface(), m_progCollection)
209         , m_debugReportRecorder (testCtx.getCommandLine().isValidationEnabled()
210                                                          ? createDebugReportRecorder(m_library->getPlatformInterface(),
211                                                                                                                  m_context.getInstanceInterface(),
212                                                                                                                  m_context.getInstance())
213                                                          : MovePtr<vk::DebugReportRecorder>(DE_NULL))
214         , m_instance                    (DE_NULL)
215 {
216 }
217
218 TestCaseExecutor::~TestCaseExecutor (void)
219 {
220         delete m_instance;
221 }
222
223 void TestCaseExecutor::init (tcu::TestCase* testCase, const std::string& casePath)
224 {
225         const TestCase*                         vktCase                                         = dynamic_cast<TestCase*>(testCase);
226         tcu::TestLog&                           log                                                     = m_context.getTestContext().getLog();
227         const deUint32                          usedVulkanVersion                       = m_context.getUsedApiVersion();
228         const vk::SpirvVersion          spirvVersionForGlsl                     = vk::getSpirvVersionForGlsl(usedVulkanVersion);
229         const vk::SpirvVersion          spirvVersionForAsm                      = vk::getSpirvVersionForAsm(usedVulkanVersion);
230         vk::ShaderBuildOptions          defaultGlslBuildOptions         (spirvVersionForGlsl, 0u);
231         vk::ShaderBuildOptions          defaultHlslBuildOptions         (spirvVersionForGlsl, 0u);
232         vk::SpirVAsmBuildOptions        defaultSpirvAsmBuildOptions     (spirvVersionForAsm);
233         vk::SourceCollections           sourceProgs                                     (usedVulkanVersion, defaultGlslBuildOptions, defaultHlslBuildOptions, defaultSpirvAsmBuildOptions);
234
235         DE_UNREF(casePath); // \todo [2015-03-13 pyry] Use this to identify ProgramCollection storage path
236
237         if (!vktCase)
238                 TCU_THROW(InternalError, "Test node not an instance of vkt::TestCase");
239
240         m_progCollection.clear();
241         vktCase->initPrograms(sourceProgs);
242
243         for (vk::GlslSourceCollection::Iterator progIter = sourceProgs.glslSources.begin(); progIter != sourceProgs.glslSources.end(); ++progIter)
244         {
245                 if (progIter.getProgram().buildOptions.targetVersion > vk::getSpirvVersionForGlsl(m_context.getUsedApiVersion()))
246                         TCU_THROW(NotSupportedError, "Shader requires SPIR-V higher than available");
247
248                 const vk::ProgramBinary* const binProg = buildProgram<glu::ShaderProgramInfo, vk::GlslSourceCollection::Iterator>(casePath, progIter, m_prebuiltBinRegistry, log, &m_progCollection);
249
250                 try
251                 {
252                         std::ostringstream disasm;
253
254                         vk::disassembleProgram(*binProg, &disasm, spirvVersionForGlsl);
255
256                         log << vk::SpirVAsmSource(disasm.str());
257                 }
258                 catch (const tcu::NotSupportedError& err)
259                 {
260                         log << err;
261                 }
262         }
263
264         for (vk::HlslSourceCollection::Iterator progIter = sourceProgs.hlslSources.begin(); progIter != sourceProgs.hlslSources.end(); ++progIter)
265         {
266                 if (progIter.getProgram().buildOptions.targetVersion > vk::getSpirvVersionForGlsl(m_context.getUsedApiVersion()))
267                         TCU_THROW(NotSupportedError, "Shader requires SPIR-V higher than available");
268
269                 const vk::ProgramBinary* const binProg = buildProgram<glu::ShaderProgramInfo, vk::HlslSourceCollection::Iterator>(casePath, progIter, m_prebuiltBinRegistry, log, &m_progCollection);
270
271                 try
272                 {
273                         std::ostringstream disasm;
274
275                         vk::disassembleProgram(*binProg, &disasm, spirvVersionForGlsl);
276
277                         log << vk::SpirVAsmSource(disasm.str());
278                 }
279                 catch (const tcu::NotSupportedError& err)
280                 {
281                         log << err;
282                 }
283         }
284
285         for (vk::SpirVAsmCollection::Iterator asmIterator = sourceProgs.spirvAsmSources.begin(); asmIterator != sourceProgs.spirvAsmSources.end(); ++asmIterator)
286         {
287                 if (asmIterator.getProgram().buildOptions.targetVersion > vk::getSpirvVersionForAsm(m_context.getUsedApiVersion()))
288                         TCU_THROW(NotSupportedError, "Shader requires SPIR-V higher than available");
289
290                 buildProgram<vk::SpirVProgramInfo, vk::SpirVAsmCollection::Iterator>(casePath, asmIterator, m_prebuiltBinRegistry, log, &m_progCollection);
291         }
292
293         DE_ASSERT(!m_instance);
294         m_instance = vktCase->createInstance(m_context);
295 }
296
297 void TestCaseExecutor::deinit (tcu::TestCase*)
298 {
299         delete m_instance;
300         m_instance = DE_NULL;
301
302         // Collect and report any debug messages
303         if (m_debugReportRecorder)
304         {
305                 // \note We are not logging INFORMATION and DEBUG messages
306                 static const vk::VkDebugReportFlagsEXT                  errorFlags              = vk::VK_DEBUG_REPORT_ERROR_BIT_EXT;
307                 static const vk::VkDebugReportFlagsEXT                  logFlags                = errorFlags
308                                                                                                                                                 | vk::VK_DEBUG_REPORT_WARNING_BIT_EXT
309                                                                                                                                                 | vk::VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
310
311                 typedef vk::DebugReportRecorder::MessageList    DebugMessages;
312
313                 const DebugMessages&    messages        = m_debugReportRecorder->getMessages();
314                 tcu::TestLog&                   log                     = m_context.getTestContext().getLog();
315
316                 if (messages.begin() != messages.end())
317                 {
318                         const tcu::ScopedLogSection     section         (log, "DebugMessages", "Debug Messages");
319                         int                                                     numErrors       = 0;
320
321                         for (DebugMessages::const_iterator curMsg = messages.begin(); curMsg != messages.end(); ++curMsg)
322                         {
323                                 if ((curMsg->flags & logFlags) != 0)
324                                         log << tcu::TestLog::Message << *curMsg << tcu::TestLog::EndMessage;
325
326                                 if ((curMsg->flags & errorFlags) != 0)
327                                         numErrors += 1;
328                         }
329
330                         m_debugReportRecorder->clearMessages();
331
332                         if (numErrors > 0)
333                                 m_context.getTestContext().setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, (de::toString(numErrors) + " API usage errors found").c_str());
334                 }
335         }
336 }
337
338 tcu::TestNode::IterateResult TestCaseExecutor::iterate (tcu::TestCase*)
339 {
340         DE_ASSERT(m_instance);
341
342         const tcu::TestStatus   result  = m_instance->iterate();
343
344         if (result.isComplete())
345         {
346                 // Vulkan tests shouldn't set result directly
347                 DE_ASSERT(m_context.getTestContext().getTestResult() == QP_TEST_RESULT_LAST);
348                 m_context.getTestContext().setTestResult(result.getCode(), result.getDescription().c_str());
349                 return tcu::TestNode::STOP;
350         }
351         else
352                 return tcu::TestNode::CONTINUE;
353 }
354
355 // GLSL shader tests
356
357 void createGlslTests (tcu::TestCaseGroup* glslTests)
358 {
359         tcu::TestContext&       testCtx         = glslTests->getTestContext();
360
361         // ShaderLibrary-based tests
362         static const struct
363         {
364                 const char*             name;
365                 const char*             description;
366         } s_es310Tests[] =
367         {
368                 { "arrays",                                             "Arrays"                                        },
369                 { "conditionals",                               "Conditional statements"        },
370                 { "constant_expressions",               "Constant expressions"          },
371                 { "constants",                                  "Constants"                                     },
372                 { "conversions",                                "Type conversions"                      },
373                 { "functions",                                  "Functions"                                     },
374                 { "linkage",                                    "Linking"                                       },
375                 { "scoping",                                    "Scoping"                                       },
376                 { "swizzles",                                   "Swizzles"                                      },
377         };
378
379         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_es310Tests); ndx++)
380                 glslTests->addChild(createShaderLibraryGroup(testCtx,
381                                                                                                          s_es310Tests[ndx].name,
382                                                                                                          s_es310Tests[ndx].description,
383                                                                                                          std::string("vulkan/glsl/es310/") + s_es310Tests[ndx].name + ".test").release());
384
385         // ShaderRenderCase-based tests
386         glslTests->addChild(sr::createDerivateTests                     (testCtx));
387         glslTests->addChild(sr::createDiscardTests                      (testCtx));
388         glslTests->addChild(sr::createIndexingTests                     (testCtx));
389         glslTests->addChild(sr::createLoopTests                         (testCtx));
390         glslTests->addChild(sr::createMatrixTests                       (testCtx));
391         glslTests->addChild(sr::createOperatorTests                     (testCtx));
392         glslTests->addChild(sr::createReturnTests                       (testCtx));
393         glslTests->addChild(sr::createStructTests                       (testCtx));
394         glslTests->addChild(sr::createSwitchTests                       (testCtx));
395         glslTests->addChild(sr::createTextureFunctionTests      (testCtx));
396         glslTests->addChild(sr::createTextureGatherTests        (testCtx));
397         glslTests->addChild(sr::createBuiltinVarTests           (testCtx));
398
399         // ShaderExecutor-based tests
400         glslTests->addChild(shaderexecutor::createBuiltinTests                          (testCtx));
401         glslTests->addChild(shaderexecutor::createOpaqueTypeIndexingTests       (testCtx));
402         glslTests->addChild(shaderexecutor::createAtomicOperationTests          (testCtx));
403 }
404
405 // TestPackage
406
407 TestPackage::TestPackage (tcu::TestContext& testCtx)
408         : tcu::TestPackage(testCtx, "dEQP-VK", "dEQP Vulkan Tests")
409 {
410 }
411
412 TestPackage::~TestPackage (void)
413 {
414 }
415
416 tcu::TestCaseExecutor* TestPackage::createExecutor (void) const
417 {
418         return new TestCaseExecutor(m_testCtx);
419 }
420
421 void TestPackage::init (void)
422 {
423         addChild(createTestGroup                                (m_testCtx, "info", "Build and Device Info Tests", createInfoTests));
424         addChild(api::createTests                               (m_testCtx));
425         addChild(memory::createTests                    (m_testCtx));
426         addChild(pipeline::createTests                  (m_testCtx));
427         addChild(BindingModel::createTests              (m_testCtx));
428         addChild(SpirVAssembly::createTests             (m_testCtx));
429         addChild(createTestGroup                                (m_testCtx, "glsl", "GLSL shader execution tests", createGlslTests));
430         addChild(createRenderPassTests                  (m_testCtx));
431         addChild(ubo::createTests                               (m_testCtx));
432         addChild(DynamicState::createTests              (m_testCtx));
433         addChild(ssbo::createTests                              (m_testCtx));
434         addChild(QueryPool::createTests                 (m_testCtx));
435         addChild(Draw::createTests                              (m_testCtx));
436         addChild(compute::createTests                   (m_testCtx));
437         addChild(image::createTests                             (m_testCtx));
438         addChild(wsi::createTests                               (m_testCtx));
439         addChild(synchronization::createTests   (m_testCtx));
440         addChild(sparse::createTests                    (m_testCtx));
441         addChild(tessellation::createTests              (m_testCtx));
442         addChild(rasterization::createTests             (m_testCtx));
443         addChild(clipping::createTests                  (m_testCtx));
444         addChild(FragmentOperations::createTests(m_testCtx));
445         addChild(texture::createTests                   (m_testCtx));
446         addChild(geometry::createTests                  (m_testCtx));
447         addChild(robustness::createTests                (m_testCtx));
448         addChild(MultiView::createTests                 (m_testCtx));
449         addChild(subgroups::createTests                 (m_testCtx));
450         addChild(ycbcr::createTests                             (m_testCtx));
451         addChild(ProtectedMem::createTests              (m_testCtx));
452 }
453
454 } // vkt