1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // deqp_libtester_main.cpp: Entry point for tester DLL.
7
8 #include <cstdio>
9 #include <iostream>
10
11 #include "angle_deqp_libtester.h"
12 #include "common/angleutils.h"
13 #include "common/system_utils.h"
14 #include "deMath.h"
15 #include "deUniquePtr.hpp"
16 #include "platform/PlatformMethods.h"
17 #include "tcuANGLEPlatform.h"
18 #include "tcuApp.hpp"
19 #include "tcuCommandLine.hpp"
20 #include "tcuDefs.hpp"
21 #include "tcuPlatform.hpp"
22 #include "tcuRandomOrderExecutor.h"
23 #include "tcuResource.hpp"
24 #include "tcuTestLog.hpp"
25 #include "util/OSWindow.h"
26
27 namespace
28 {
29
30 tcu::Platform *g_platform = nullptr;
31 tcu::CommandLine *g_cmdLine = nullptr;
32 tcu::DirArchive *g_archive = nullptr;
33 tcu::TestLog *g_log = nullptr;
34 tcu::TestContext *g_testCtx = nullptr;
35 tcu::TestPackageRoot *g_root = nullptr;
36 tcu::RandomOrderExecutor *g_executor = nullptr;
37
GetLogFileName(std::string deqpDataDir)38 std::string GetLogFileName(std::string deqpDataDir)
39 {
40 #if (DE_OS == DE_OS_ANDROID)
41 // On Android executable dir is not writable, so use data dir instead
42 return std::string("/data/data/com.android.angle.test/") + g_cmdLine->getLogFileName();
43 #else
44 return g_cmdLine->getLogFileName();
45 #endif
46 }
47
48 } // anonymous namespace
49
deqp_libtester_init_platform(int argc,const char * argv[],void * logErrorFunc,const dEQPOptions & options)50 ANGLE_LIBTESTER_EXPORT bool deqp_libtester_init_platform(int argc,
51 const char *argv[],
52 void *logErrorFunc,
53 const dEQPOptions &options)
54 {
55 try
56 {
57 #if (DE_OS != DE_OS_WIN32)
58 // Set stdout to line-buffered mode (will be fully buffered by default if stdout is pipe).
59 setvbuf(stdout, DE_NULL, _IOLBF, 4 * 1024);
60 #endif
61 g_platform = CreateANGLEPlatform(reinterpret_cast<angle::LogErrorFunc>(logErrorFunc),
62 options.preRotation);
63
64 if (!deSetRoundingMode(DE_ROUNDINGMODE_TO_NEAREST_EVEN))
65 {
66 std::cout << "Failed to set floating point rounding mode." << std::endl;
67 return false;
68 }
69
70 constexpr size_t kMaxDataDirLen = 1000;
71 char deqpDataDir[kMaxDataDirLen];
72 if (!angle::FindTestDataPath(ANGLE_DEQP_DATA_DIR, deqpDataDir, kMaxDataDirLen))
73 {
74 std::cout << "Failed to find dEQP data directory." << std::endl;
75 return false;
76 }
77
78 g_cmdLine = new tcu::CommandLine(argc, argv);
79 g_archive = new tcu::DirArchive(deqpDataDir);
80 g_log = new tcu::TestLog(GetLogFileName(deqpDataDir).c_str(), g_cmdLine->getLogFlags());
81 g_testCtx = new tcu::TestContext(*g_platform, *g_archive, *g_log, *g_cmdLine, DE_NULL);
82 g_root = new tcu::TestPackageRoot(*g_testCtx, tcu::TestPackageRegistry::getSingleton());
83 g_executor =
84 new tcu::RandomOrderExecutor(*g_root, *g_testCtx, options.enableRenderDocCapture);
85 }
86 catch (const std::exception &e)
87 {
88 tcu::die("%s", e.what());
89 return false;
90 }
91
92 return true;
93 }
94
95 // Exported to the tester app.
deqp_libtester_main(int argc,const char * argv[])96 ANGLE_LIBTESTER_EXPORT int deqp_libtester_main(int argc, const char *argv[])
97 {
98 if (!deqp_libtester_init_platform(argc, argv, nullptr, {}))
99 {
100 tcu::die("Could not initialize the dEQP platform");
101 }
102
103 try
104 {
105 de::UniquePtr<tcu::App> app(new tcu::App(*g_platform, *g_archive, *g_log, *g_cmdLine));
106
107 // Main loop.
108 for (;;)
109 {
110 if (!app->iterate())
111 break;
112 }
113 }
114 catch (const std::exception &e)
115 {
116 deqp_libtester_shutdown_platform();
117 tcu::die("%s", e.what());
118 }
119
120 deqp_libtester_shutdown_platform();
121 return 0;
122 }
123
deqp_libtester_shutdown_platform()124 ANGLE_LIBTESTER_EXPORT void deqp_libtester_shutdown_platform()
125 {
126 delete g_executor;
127 g_executor = nullptr;
128 delete g_root;
129 g_root = nullptr;
130 delete g_testCtx;
131 g_testCtx = nullptr;
132 delete g_log;
133 g_log = nullptr;
134 delete g_archive;
135 g_archive = nullptr;
136 delete g_cmdLine;
137 g_cmdLine = nullptr;
138 delete g_platform;
139 g_platform = nullptr;
140 }
141
deqp_libtester_run(const char * caseName)142 ANGLE_LIBTESTER_EXPORT dEQPTestResult deqp_libtester_run(const char *caseName)
143 {
144 const char *emptyString = "";
145 if (g_platform == nullptr)
146 {
147 tcu::die("Failed to initialize platform.");
148 }
149
150 try
151 {
152 // Poll platform events
153 const bool platformOk = g_platform->processEvents();
154
155 if (platformOk)
156 {
157 const tcu::TestStatus &result = g_executor->execute(caseName);
158 switch (result.getCode())
159 {
160 case QP_TEST_RESULT_PASS:
161 return dEQPTestResult::Pass;
162 case QP_TEST_RESULT_NOT_SUPPORTED:
163 std::cout << "Not supported! " << result.getDescription() << std::endl;
164 return dEQPTestResult::NotSupported;
165 case QP_TEST_RESULT_QUALITY_WARNING:
166 std::cout << "Quality warning! " << result.getDescription() << std::endl;
167 return dEQPTestResult::Pass;
168 case QP_TEST_RESULT_COMPATIBILITY_WARNING:
169 std::cout << "Compatiblity warning! " << result.getDescription() << std::endl;
170 return dEQPTestResult::Pass;
171 default:
172 return dEQPTestResult::Fail;
173 }
174 }
175 else
176 {
177 std::cout << "Aborted test!" << std::endl;
178 }
179 }
180 catch (const std::exception &e)
181 {
182 std::cout << "Exception running test: " << e.what() << std::endl;
183 return dEQPTestResult::Exception;
184 }
185
186 return dEQPTestResult::Fail;
187 }
188