• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "tcuApp.hpp"
18 #include "tcuCommandLine.hpp"
19 #include "tcuDefs.hpp"
20 #include "tcuPlatform.hpp"
21 #include "tcuRandomOrderExecutor.h"
22 #include "tcuResource.hpp"
23 #include "tcuTestLog.hpp"
24 
25 tcu::Platform *CreateANGLEPlatform(angle::LogErrorFunc logErrorFunc);
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 
38 const char *kDataPaths[] = {
39     ".",
40     "../../sdcard/chromium_tests_root",
41     "../../sdcard/chromium_tests_root/third_party/angle/third_party/VK-GL-CTS/src",
42     "../../third_party/angle/third_party/VK-GL-CTS/src",
43     "../../third_party/VK-GL-CTS/src",
44     "third_party/VK-GL-CTS/src",
45 };
46 
FindDataDir(std::string * dataDirOut)47 bool FindDataDir(std::string *dataDirOut)
48 {
49     for (const char *dataPath : kDataPaths)
50     {
51         std::stringstream dirStream;
52         dirStream << angle::GetExecutableDirectory() << "/" << dataPath << "/"
53                   << ANGLE_DEQP_DATA_DIR;
54         std::string candidateDataDir = dirStream.str();
55 
56         if (angle::IsDirectory(candidateDataDir.c_str()))
57         {
58             *dataDirOut = candidateDataDir;
59             return true;
60         }
61     }
62 
63     return false;
64 }
65 
GetLogFileName(std::string deqpDataDir)66 std::string GetLogFileName(std::string deqpDataDir)
67 {
68 #if (DE_OS == DE_OS_ANDROID)
69     // On Android executable dir is not writable, so use data dir instead
70     return deqpDataDir + "/" + g_cmdLine->getLogFileName();
71 #else
72     return g_cmdLine->getLogFileName();
73 #endif
74 }
75 
76 }  // anonymous namespace
77 
deqp_libtester_init_platform(int argc,const char * argv[],void * logErrorFunc)78 ANGLE_LIBTESTER_EXPORT bool deqp_libtester_init_platform(int argc,
79                                                          const char *argv[],
80                                                          void *logErrorFunc)
81 {
82     try
83     {
84 #if (DE_OS != DE_OS_WIN32)
85         // Set stdout to line-buffered mode (will be fully buffered by default if stdout is pipe).
86         setvbuf(stdout, DE_NULL, _IOLBF, 4 * 1024);
87 #endif
88         g_platform = CreateANGLEPlatform(reinterpret_cast<angle::LogErrorFunc>(logErrorFunc));
89 
90         if (!deSetRoundingMode(DE_ROUNDINGMODE_TO_NEAREST_EVEN))
91         {
92             std::cout << "Failed to set floating point rounding mode." << std::endl;
93             return false;
94         }
95 
96         std::string deqpDataDir;
97         if (!FindDataDir(&deqpDataDir))
98         {
99             std::cout << "Failed to find dEQP data directory." << std::endl;
100             return false;
101         }
102 
103         g_cmdLine = new tcu::CommandLine(argc, argv);
104         g_archive = new tcu::DirArchive(deqpDataDir.c_str());
105         g_log     = new tcu::TestLog(GetLogFileName(deqpDataDir).c_str(), g_cmdLine->getLogFlags());
106         g_testCtx = new tcu::TestContext(*g_platform, *g_archive, *g_log, *g_cmdLine, DE_NULL);
107         g_root    = new tcu::TestPackageRoot(*g_testCtx, tcu::TestPackageRegistry::getSingleton());
108         g_executor = new tcu::RandomOrderExecutor(*g_root, *g_testCtx);
109     }
110     catch (const std::exception &e)
111     {
112         tcu::die("%s", e.what());
113         return false;
114     }
115 
116     return true;
117 }
118 
119 // Exported to the tester app.
deqp_libtester_main(int argc,const char * argv[])120 ANGLE_LIBTESTER_EXPORT int deqp_libtester_main(int argc, const char *argv[])
121 {
122     if (!deqp_libtester_init_platform(argc, argv, nullptr))
123     {
124         tcu::die("Could not initialize the dEQP platform");
125     }
126 
127     try
128     {
129         de::UniquePtr<tcu::App> app(new tcu::App(*g_platform, *g_archive, *g_log, *g_cmdLine));
130 
131         // Main loop.
132         for (;;)
133         {
134             if (!app->iterate())
135                 break;
136         }
137     }
138     catch (const std::exception &e)
139     {
140         deqp_libtester_shutdown_platform();
141         tcu::die("%s", e.what());
142     }
143 
144     deqp_libtester_shutdown_platform();
145     return 0;
146 }
147 
deqp_libtester_shutdown_platform()148 ANGLE_LIBTESTER_EXPORT void deqp_libtester_shutdown_platform()
149 {
150     delete g_executor;
151     g_executor = nullptr;
152     delete g_root;
153     g_root = nullptr;
154     delete g_testCtx;
155     g_testCtx = nullptr;
156     delete g_log;
157     g_log = nullptr;
158     delete g_archive;
159     g_archive = nullptr;
160     delete g_cmdLine;
161     g_cmdLine = nullptr;
162     delete g_platform;
163     g_platform = nullptr;
164 }
165 
deqp_libtester_run(const char * caseName)166 ANGLE_LIBTESTER_EXPORT TestResult deqp_libtester_run(const char *caseName)
167 {
168     const char *emptyString = "";
169     if (g_platform == nullptr && !deqp_libtester_init_platform(1, &emptyString, nullptr))
170     {
171         tcu::die("Failed to initialize platform.");
172     }
173 
174     try
175     {
176         // Poll platform events
177         const bool platformOk = g_platform->processEvents();
178 
179         if (platformOk)
180         {
181             const tcu::TestStatus &result = g_executor->execute(caseName);
182             switch (result.getCode())
183             {
184                 case QP_TEST_RESULT_PASS:
185                     return TestResult::Pass;
186                 case QP_TEST_RESULT_NOT_SUPPORTED:
187                     std::cout << "Not supported! " << result.getDescription() << std::endl;
188                     return TestResult::NotSupported;
189                 case QP_TEST_RESULT_QUALITY_WARNING:
190                     std::cout << "Quality warning! " << result.getDescription() << std::endl;
191                     return TestResult::Pass;
192                 case QP_TEST_RESULT_COMPATIBILITY_WARNING:
193                     std::cout << "Compatiblity warning! " << result.getDescription() << std::endl;
194                     return TestResult::Pass;
195                 default:
196                     return TestResult::Fail;
197             }
198         }
199         else
200         {
201             std::cout << "Aborted test!" << std::endl;
202         }
203     }
204     catch (const std::exception &e)
205     {
206         std::cout << "Exception running test: " << e.what() << std::endl;
207         return TestResult::Exception;
208     }
209 
210     return TestResult::Fail;
211 }
212