diff options
Diffstat (limited to 'gfx/angle/src/tests/deqp_support/angle_deqp_libtester_main.cpp')
-rwxr-xr-x | gfx/angle/src/tests/deqp_support/angle_deqp_libtester_main.cpp | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/gfx/angle/src/tests/deqp_support/angle_deqp_libtester_main.cpp b/gfx/angle/src/tests/deqp_support/angle_deqp_libtester_main.cpp new file mode 100755 index 000000000..90727f390 --- /dev/null +++ b/gfx/angle/src/tests/deqp_support/angle_deqp_libtester_main.cpp @@ -0,0 +1,250 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// deqp_libtester_main.cpp: Entry point for tester DLL. + +#include <cstdio> +#include <iostream> + +#include "angle_deqp_libtester.h" +#include "common/angleutils.h" +#include "deMath.h" +#include "deUniquePtr.hpp" +#include "tcuApp.hpp" +#include "tcuCommandLine.hpp" +#include "tcuDefs.hpp" +#include "tcuPlatform.hpp" +#include "tcuRandomOrderExecutor.h" +#include "tcuResource.hpp" +#include "tcuTestLog.hpp" +#include "system_utils.h" + +#if (DE_OS == DE_OS_WIN32) +#include <Windows.h> +#elif (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) +#include <sys/unistd.h> +#include <sys/stat.h> +#include <sys/types.h> +#elif (DE_OS == DE_OS_ANDROID) +#include <sys/stat.h> +#endif + +tcu::Platform *createPlatform(); + +namespace +{ + +tcu::Platform *g_platform = nullptr; +tcu::CommandLine *g_cmdLine = nullptr; +tcu::DirArchive *g_archive = nullptr; +tcu::TestLog *g_log = nullptr; +tcu::TestContext *g_testCtx = nullptr; +tcu::TestPackageRoot *g_root = nullptr; +tcu::RandomOrderExecutor *g_executor = nullptr; + +const char *g_dEQPDataSearchDirs[] = { + "data", + "third_party/deqp/data", + "../third_party/deqp/src/data", + "deqp_support/data", + "third_party/deqp/src/data", + "../../third_party/deqp/src/data", + "../../../third_party/deqp/src/data", + "../../sdcard/chromium_tests_root/third_party/deqp/src/data", +}; + +// TODO(jmadill): upstream to dEQP? +#if (DE_OS == DE_OS_WIN32) +deBool deIsDir(const char *filename) +{ + WIN32_FILE_ATTRIBUTE_DATA fileInformation; + + BOOL result = GetFileAttributesExA(filename, GetFileExInfoStandard, &fileInformation); + if (result) + { + DWORD attribs = fileInformation.dwFileAttributes; + return (attribs != INVALID_FILE_ATTRIBUTES) && ((attribs & FILE_ATTRIBUTE_DIRECTORY) > 0); + } + + return false; +} +#elif (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_ANDROID) +deBool deIsDir(const char *filename) +{ + struct stat st; + int result = stat(filename, &st); + return result == 0 && ((st.st_mode & S_IFDIR) == S_IFDIR); +} +#else +#error TODO(jmadill): support other platforms +#endif + +bool FindDataDir(std::string *dataDirOut) +{ + for (auto searchDir : g_dEQPDataSearchDirs) + { + if (deIsDir((std::string(searchDir) + "/gles2").c_str())) + { + *dataDirOut = searchDir; + return true; + } + + std::stringstream dirStream; + dirStream << angle::GetExecutableDirectory() << "/" << searchDir; + std::string dataDir = dirStream.str(); + dirStream << "/gles2"; + std::string searchPath = dirStream.str(); + + if (deIsDir(searchPath.c_str())) + { + *dataDirOut = dataDir; + return true; + } + } + + return false; +} + +std::string GetLogFileName(std::string deqpDataDir) +{ +#if (DE_OS == DE_OS_ANDROID) + // On Android executable dir is not writable, so use data dir instead + return deqpDataDir + "/" + g_cmdLine->getLogFileName(); +#else + return g_cmdLine->getLogFileName(); +#endif +} + +} // anonymous namespace + +ANGLE_LIBTESTER_EXPORT bool deqp_libtester_init_platform(int argc, const char *argv[]) +{ + try + { +#if (DE_OS != DE_OS_WIN32) + // Set stdout to line-buffered mode (will be fully buffered by default if stdout is pipe). + setvbuf(stdout, DE_NULL, _IOLBF, 4 * 1024); +#endif + g_platform = createPlatform(); + + if (!deSetRoundingMode(DE_ROUNDINGMODE_TO_NEAREST)) + { + std::cout << "Failed to set floating point rounding mode." << std::endl; + return false; + } + + std::string deqpDataDir; + if (!FindDataDir(&deqpDataDir)) + { + std::cout << "Failed to find dEQP data directory." << std::endl; + return false; + } + + g_cmdLine = new tcu::CommandLine(argc, argv); + g_archive = new tcu::DirArchive(deqpDataDir.c_str()); + g_log = new tcu::TestLog(GetLogFileName(deqpDataDir).c_str(), g_cmdLine->getLogFlags()); + g_testCtx = new tcu::TestContext(*g_platform, *g_archive, *g_log, *g_cmdLine, DE_NULL); + g_root = new tcu::TestPackageRoot(*g_testCtx, tcu::TestPackageRegistry::getSingleton()); + g_executor = new tcu::RandomOrderExecutor(*g_root, *g_testCtx); + } + catch (const std::exception& e) + { + tcu::die("%s", e.what()); + return false; + } + + return true; +} + +// Exported to the tester app. +ANGLE_LIBTESTER_EXPORT int deqp_libtester_main(int argc, const char *argv[]) +{ + if (!deqp_libtester_init_platform(argc, argv)) + { + tcu::die("Could not initialize the dEQP platform"); + } + + try + { + de::UniquePtr<tcu::App> app(new tcu::App(*g_platform, *g_archive, *g_log, *g_cmdLine)); + + // Main loop. + for (;;) + { + if (!app->iterate()) + break; + } + } + catch (const std::exception &e) + { + deqp_libtester_shutdown_platform(); + tcu::die("%s", e.what()); + } + + deqp_libtester_shutdown_platform(); + return 0; +} + +ANGLE_LIBTESTER_EXPORT void deqp_libtester_shutdown_platform() +{ + delete g_executor; + g_executor = nullptr; + delete g_root; + g_root = nullptr; + delete g_testCtx; + g_testCtx = nullptr; + delete g_log; + g_log = nullptr; + delete g_archive; + g_archive = nullptr; + delete g_cmdLine; + g_cmdLine = nullptr; + delete g_platform; + g_platform = nullptr; +} + +ANGLE_LIBTESTER_EXPORT bool deqp_libtester_run(const char *caseName) +{ + const char *emptyString = ""; + if (g_platform == nullptr && !deqp_libtester_init_platform(1, &emptyString)) + { + tcu::die("Failed to initialize platform."); + } + + try + { + // Poll platform events + const bool platformOk = g_platform->processEvents(); + + if (platformOk) + { + const tcu::TestStatus &result = g_executor->execute(caseName); + switch (result.getCode()) + { + case QP_TEST_RESULT_PASS: + case QP_TEST_RESULT_NOT_SUPPORTED: + return true; + case QP_TEST_RESULT_QUALITY_WARNING: + std::cout << "Quality warning! " << result.getDescription() << std::endl; + return true; + case QP_TEST_RESULT_COMPATIBILITY_WARNING: + std::cout << "Compatiblity warning! " << result.getDescription() << std::endl; + return true; + default: + return false; + } + } + else + { + std::cout << "Aborted test!" << std::endl; + } + } + catch (const std::exception &e) + { + std::cout << "Exception running test: " << e.what() << std::endl; + } + + return false; +} |