| // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "glbench/main.h" |
| |
| #include <gflags/gflags.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #include <ctime> |
| #include <string> |
| #include <vector> |
| |
| #include "base/logging.h" |
| #include "base/strings/string_split.h" |
| #include "base/strings/string_util.h" |
| |
| #include "glbench/glinterface.h" |
| #include "glbench/utils.h" |
| |
| #include "glbench/all_tests.h" |
| #include "glbench/testbase.h" |
| |
| using std::string; |
| using std::vector; |
| |
| DEFINE_int32(duration, 0, |
| "Run all tests again and again in a loop for at least this many " |
| "seconds."); |
| DEFINE_string(tests, "", |
| "Colon-separated list of tests to run; all tests if omitted."); |
| DEFINE_string(blacklist, "", "colon-separated list of tests to disable"); |
| DEFINE_bool(hasty, false, |
| "Run a smaller set of tests with less accurate results. " |
| "Useful for running in BVT or debugging a failure. Implies " |
| "notemp"); |
| DEFINE_bool(list, false, "List available tests"); |
| DEFINE_bool(notemp, false, "Skip temperature checking"); |
| |
| GLint g_max_texture_size; |
| bool g_hasty; |
| bool g_notemp; |
| |
| bool test_is_enabled(glbench::TestBase* test, |
| const vector<string>& enabled_tests) { |
| if (enabled_tests.empty()) |
| return true; |
| |
| const char* test_name = test->Name(); |
| for (const std::string& test : enabled_tests) { |
| // This is not very precise, but will do until there's a need for something |
| // more flexible. |
| if (strstr(test_name, test.c_str())) |
| return true; |
| } |
| |
| return false; |
| } |
| |
| bool test_is_disabled(glbench::TestBase* test, |
| const vector<string>& disabled_tests) { |
| if (disabled_tests.empty()) |
| return false; |
| |
| const char* test_name = test->Name(); |
| for (vector<string>::const_iterator i = disabled_tests.begin(); |
| i != disabled_tests.end(); ++i) { |
| // This is not very precise, but will do until there's a need for something |
| // more flexible. |
| if (strstr(test_name, i->c_str())) |
| return true; |
| } |
| |
| return false; |
| } |
| |
| void printDateTime(void) { |
| struct tm ttime; |
| time_t tm = time(0); |
| char time_string[64]; |
| localtime_r(&tm, &ttime); |
| strftime(time_string, 63, "%c", &ttime); |
| printf("# DateTime: %s\n", time_string); |
| } |
| |
| bool PassesSanityCheck(void) { |
| GLint size[2]; |
| glGetIntegerv(GL_MAX_VIEWPORT_DIMS, size); |
| printf("# MAX_VIEWPORT_DIMS=(%d, %d)\n", size[0], size[1]); |
| if (size[0] < g_width || size[1] < g_height) { |
| printf("# Error: MAX_VIEWPORT_DIMS=(%d, %d) are too small.\n", |
| size[0], size[1]); |
| return false; |
| } |
| glGetIntegerv(GL_MAX_TEXTURE_SIZE, size); |
| printf("# GL_MAX_TEXTURE_SIZE=%d\n", size[0]); |
| if (size[0] < g_width || size[0] < g_height) { |
| printf("# Error: MAX_TEXTURE_SIZE=%d is too small.\n", |
| size[0]); |
| return false; |
| } |
| g_max_texture_size = size[0]; |
| |
| return true; |
| } |
| |
| int main(int argc, char *argv[]) { |
| SetBasePathFromSelfExe("../share/glbench"); |
| google::ParseCommandLineFlags(&argc, &argv, false); |
| |
| g_main_gl_interface.reset(GLInterface::Create()); |
| if (!g_main_gl_interface->Init()) { |
| printf("# Error: Failed to initialize %s.\n", argv[0]); |
| return 1; |
| } |
| |
| printf("# board_id: %s - %s\n", |
| glGetString(GL_VENDOR), glGetString(GL_RENDERER)); |
| if (!PassesSanityCheck()) |
| return 1; |
| g_main_gl_interface->Cleanup(); |
| |
| if (argc == 1) { |
| printf("# Usage: %s [-save [-outdir=<directory>]] to save images\n", |
| argv[0]); |
| } else { |
| printf("# Running: "); |
| for (int i = 0; i < argc; i++) printf("%s ", argv[i]); |
| printf("\n"); |
| } |
| printDateTime(); |
| |
| g_hasty = FLAGS_hasty; |
| g_notemp = FLAGS_notemp || g_hasty; |
| |
| if (!g_notemp) |
| g_initial_temperature = GetMachineTemperature(); |
| |
| vector<string> enabled_tests, disabled_tests; |
| base::SplitString(FLAGS_tests, ':', &enabled_tests); |
| base::SplitString(FLAGS_blacklist, ':', &disabled_tests); |
| |
| glbench::TestBase* tests[] = { |
| // Please add new tests at the end of this list as tests are known to bleed |
| // state. Reordering them or inserting a new test may cause a change in the |
| // output images and MD5 causing graphics_GLBench failures. |
| // TODO(ihf): Fix this. |
| glbench::GetSwapTest(), |
| glbench::GetContextTest(), |
| glbench::GetClearTest(), |
| glbench::GetFillRateTest(), |
| glbench::GetWindowManagerCompositingTest(false), |
| glbench::GetWindowManagerCompositingTest(true), |
| glbench::GetTriangleSetupTest(), |
| glbench::GetYuvToRgbTest(), |
| glbench::GetReadPixelTest(), |
| glbench::GetAttributeFetchShaderTest(), |
| glbench::GetVaryingsAndDdxyShaderTest(), |
| glbench::GetTextureReuseTest(), |
| glbench::GetTextureUpdateTest(), |
| glbench::GetTextureUploadTest(), |
| glbench::GetFboFillRateTest(), |
| }; |
| |
| if (FLAGS_list) { |
| for (unsigned int i = 0; i < arraysize(tests); i++) |
| printf("%s\n", tests[i]->Name()); |
| return 0; |
| } |
| |
| uint64_t done = GetUTime() + 1000000ULL * FLAGS_duration; |
| do { |
| for (unsigned int i = 0; i < arraysize(tests); i++) { |
| if (!test_is_enabled(tests[i], enabled_tests) || |
| test_is_disabled(tests[i], disabled_tests)) |
| continue; |
| if (!g_main_gl_interface->Init()) { |
| printf("Initialize failed\n"); |
| return 1; |
| } |
| glbench::ClearBuffers(); |
| tests[i]->Run(); |
| g_main_gl_interface->Cleanup(); |
| } |
| } while (GetUTime() < done); |
| |
| for (unsigned int i = 0; i < arraysize(tests); i++) { |
| delete tests[i]; |
| tests[i] = NULL; |
| } |
| |
| printDateTime(); |
| // Signal to harness that we finished normally. |
| printf("@TEST_END\n"); |
| |
| return 0; |
| } |