1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 Google Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and/or associated documentation files (the
9 * "Materials"), to deal in the Materials without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Materials, and to
12 * permit persons to whom the Materials are furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice(s) and this permission notice shall be
16 * included in all copies or substantial portions of the Materials.
18 * The Materials are Confidential Information as defined by the
19 * Khronos Membership Agreement until designated non-confidential by
20 * Khronos, at which point this condition clause shall be removed.
22 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
32 * \brief Utility for pre-compiling source programs to SPIR-V
33 *//*--------------------------------------------------------------------*/
35 #include "tcuDefs.hpp"
36 #include "tcuCommandLine.hpp"
37 #include "tcuPlatform.hpp"
38 #include "tcuResource.hpp"
39 #include "tcuTestLog.hpp"
40 #include "tcuTestHierarchyIterator.hpp"
41 #include "deUniquePtr.hpp"
42 #include "vkPrograms.hpp"
43 #include "vkBinaryRegistry.hpp"
44 #include "vktTestCase.hpp"
45 #include "vktTestPackage.hpp"
46 #include "deUniquePtr.hpp"
47 #include "deCommandLine.hpp"
58 tcu::TestPackageRoot* createRoot (tcu::TestContext& testCtx)
60 vector<tcu::TestNode*> children;
61 children.push_back(new TestPackage(testCtx));
62 return new tcu::TestPackageRoot(testCtx, children);
85 BuildStats buildPrograms (tcu::TestContext& testCtx, const std::string& dstPath, BuildMode mode)
87 const UniquePtr<tcu::TestPackageRoot> root (createRoot(testCtx));
88 tcu::DefaultHierarchyInflater inflater (testCtx);
89 tcu::TestHierarchyIterator iterator (*root, inflater, testCtx.getCommandLine());
90 const tcu::DirArchive srcArchive (dstPath.c_str());
91 UniquePtr<vk::BinaryRegistryWriter> writer (mode == BUILDMODE_BUILD ? new vk::BinaryRegistryWriter(dstPath) : DE_NULL);
92 UniquePtr<vk::BinaryRegistryReader> reader (mode == BUILDMODE_VERIFY ? new vk::BinaryRegistryReader(srcArchive, "") : DE_NULL);
95 while (iterator.getState() != tcu::TestHierarchyIterator::STATE_FINISHED)
97 if (iterator.getState() == tcu::TestHierarchyIterator::STATE_ENTER_NODE &&
98 tcu::isTestNodeTypeExecutable(iterator.getNode()->getNodeType()))
100 const TestCase* const testCase = dynamic_cast<TestCase*>(iterator.getNode());
101 const string casePath = iterator.getNodePath();
102 vk::SourceCollection progs;
104 tcu::print("%s\n", casePath.c_str());
106 testCase->initPrograms(progs);
108 for (vk::SourceCollection::Iterator progIter = progs.begin(); progIter != progs.end(); ++progIter)
112 const vk::ProgramIdentifier progId (casePath, progIter.getName());
113 glu::ShaderProgramInfo buildInfo;
114 const UniquePtr<vk::ProgramBinary> binary (vk::buildProgram(progIter.getProgram(), vk::PROGRAM_FORMAT_SPIRV, &buildInfo));
116 if (mode == BUILDMODE_BUILD)
117 writer->storeProgram(progId, *binary);
120 DE_ASSERT(mode == BUILDMODE_VERIFY);
122 const UniquePtr<vk::ProgramBinary> storedBinary (reader->loadProgram(progId));
124 if (binary->getSize() != storedBinary->getSize())
125 throw tcu::Exception("Binary size doesn't match");
127 if (deMemCmp(binary->getBinary(), storedBinary->getBinary(), binary->getSize()))
128 throw tcu::Exception("Binary contents don't match");
131 tcu::print(" OK: %s\n", progIter.getName().c_str());
132 stats.numSucceeded += 1;
134 catch (const std::exception& e)
136 tcu::print(" ERROR: %s: %s\n", progIter.getName().c_str(), e.what());
137 stats.numFailed += 1;
153 DE_DECLARE_COMMAND_LINE_OPT(DstPath, std::string);
154 DE_DECLARE_COMMAND_LINE_OPT(Mode, vkt::BuildMode);
158 void registerOptions (de::cmdline::Parser& parser)
160 using de::cmdline::Option;
161 using de::cmdline::NamedValue;
163 static const NamedValue<vkt::BuildMode> s_modes[] =
165 { "build", vkt::BUILDMODE_BUILD },
166 { "verify", vkt::BUILDMODE_VERIFY }
169 parser << Option<opt::DstPath> ("d", "dst-path", "Destination path", ".")
170 << Option<opt::Mode> ("m", "mode", "Build mode", s_modes, "build");
173 int main (int argc, const char* argv[])
175 de::cmdline::CommandLine cmdLine;
178 de::cmdline::Parser parser;
179 registerOptions(parser);
180 if (!parser.parse(argc, argv, &cmdLine, std::cerr))
182 parser.help(std::cout);
189 const tcu::CommandLine deqpCmdLine ("unused");
190 tcu::DirArchive archive (".");
191 tcu::TestLog log (deqpCmdLine.getLogFileName(), deqpCmdLine.getLogFlags());
192 tcu::Platform platform;
193 tcu::TestContext testCtx (platform, archive, log, deqpCmdLine, DE_NULL);
195 const vkt::BuildStats stats = vkt::buildPrograms(testCtx, cmdLine.getOption<opt::DstPath>(), cmdLine.getOption<opt::Mode>());
197 tcu::print("DONE: %d passed, %d failed\n", stats.numSucceeded, stats.numFailed);
199 return stats.numFailed == 0 ? 0 : -1;
201 catch (const std::exception& e)
203 tcu::die("%s", e.what());