1 //
2 // Copyright 2019 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 // ANGLEPerfTestArgs.cpp:
7 // Parse command line arguments for angle_perftests.
8 //
9
10 #include "ANGLEPerfTestArgs.h"
11 #include <string.h>
12 #include <sstream>
13
14 #include "common/debug.h"
15 #include "util/test_utils.h"
16
17 #if defined(ANGLE_PLATFORM_ANDROID)
18 # include "util/android/AndroidWindow.h"
19 #endif
20
21 namespace angle
22 {
23
24 constexpr int kDefaultStepsPerTrial = std::numeric_limits<int>::max();
25 constexpr int kDefaultTrialTimeSeconds = 0;
26 constexpr int kDefaultTestTrials = 3;
27
28 int gStepsPerTrial = kDefaultStepsPerTrial;
29 int gMaxStepsPerformed = kDefaultMaxStepsPerformed;
30 bool gEnableTrace = false;
31 const char *gTraceFile = "ANGLETrace.json";
32 const char *gScreenshotDir = nullptr;
33 const char *gRenderTestOutputDir = nullptr;
34 bool gSaveScreenshots = false;
35 int gScreenshotFrame = kDefaultScreenshotFrame;
36 bool gVerboseLogging = false;
37 bool gWarmup = false;
38 int gTrialTimeSeconds = kDefaultTrialTimeSeconds;
39 int gTestTrials = kDefaultTestTrials;
40 bool gNoFinish = false;
41 bool gRetraceMode = false;
42 bool gMinimizeGPUWork = false;
43 bool gTraceTestValidation = false;
44 const char *gPerfCounters = nullptr;
45 const char *gUseANGLE = nullptr;
46 const char *gUseGL = nullptr;
47 bool gOffscreen = false;
48 bool gVsync = false;
49 int gFpsLimit = 0;
50 bool gRunToKeyFrame = false;
51 int gFixedTestTime = 0;
52 int gFixedTestTimeWithWarmup = 0;
53 const char *gTraceInterpreter = nullptr;
54 const char *gPrintExtensionsToFile = nullptr;
55 const char *gRequestedExtensions = nullptr;
56 bool gIncludeInactiveResources = false;
57
58 namespace
59 {
PerfTestArg(int * argc,char ** argv,int argIndex)60 bool PerfTestArg(int *argc, char **argv, int argIndex)
61 {
62 return ParseFlag("--run-to-key-frame", argc, argv, argIndex, &gRunToKeyFrame) ||
63 ParseFlag("--enable-trace", argc, argv, argIndex, &gEnableTrace) ||
64 ParseFlag("-v", argc, argv, argIndex, &gVerboseLogging) ||
65 ParseFlag("--verbose", argc, argv, argIndex, &gVerboseLogging) ||
66 ParseFlag("--verbose-logging", argc, argv, argIndex, &gVerboseLogging) ||
67 ParseFlag("--no-finish", argc, argv, argIndex, &gNoFinish) ||
68 ParseFlag("--warmup", argc, argv, argIndex, &gWarmup) ||
69 ParseCStringArg("--trace-file", argc, argv, argIndex, &gTraceFile) ||
70 ParseCStringArg("--perf-counters", argc, argv, argIndex, &gPerfCounters) ||
71 ParseIntArg("--steps-per-trial", argc, argv, argIndex, &gStepsPerTrial) ||
72 ParseIntArg("--max-steps-performed", argc, argv, argIndex, &gMaxStepsPerformed) ||
73 ParseIntArg("--fixed-test-time", argc, argv, argIndex, &gFixedTestTime) ||
74 ParseIntArg("--fixed-test-time-with-warmup", argc, argv, argIndex,
75 &gFixedTestTimeWithWarmup) ||
76 ParseIntArg("--trial-time", argc, argv, argIndex, &gTrialTimeSeconds) ||
77 ParseIntArg("--max-trial-time", argc, argv, argIndex, &gTrialTimeSeconds) ||
78 ParseIntArg("--trials", argc, argv, argIndex, &gTestTrials);
79 }
80
TraceTestArg(int * argc,char ** argv,int argIndex)81 bool TraceTestArg(int *argc, char **argv, int argIndex)
82 {
83 return ParseFlag("--retrace-mode", argc, argv, argIndex, &gRetraceMode) ||
84 ParseFlag("--validation", argc, argv, argIndex, &gTraceTestValidation) ||
85 ParseFlag("--save-screenshots", argc, argv, argIndex, &gSaveScreenshots) ||
86 ParseFlag("--offscreen", argc, argv, argIndex, &gOffscreen) ||
87 ParseFlag("--vsync", argc, argv, argIndex, &gVsync) ||
88 ParseFlag("--minimize-gpu-work", argc, argv, argIndex, &gMinimizeGPUWork) ||
89 ParseCStringArg("--trace-interpreter", argc, argv, argIndex, &gTraceInterpreter) ||
90 ParseIntArg("--screenshot-frame", argc, argv, argIndex, &gScreenshotFrame) ||
91 ParseIntArg("--fps-limit", argc, argv, argIndex, &gFpsLimit) ||
92 ParseCStringArgWithHandling("--render-test-output-dir", argc, argv, argIndex,
93 &gRenderTestOutputDir, ArgHandling::Preserve) ||
94 ParseCStringArg("--screenshot-dir", argc, argv, argIndex, &gScreenshotDir) ||
95 ParseCStringArg("--use-angle", argc, argv, argIndex, &gUseANGLE) ||
96 ParseCStringArg("--use-gl", argc, argv, argIndex, &gUseGL) ||
97 ParseCStringArg("--print-extensions-to-file", argc, argv, argIndex,
98 &gPrintExtensionsToFile) ||
99 ParseCStringArg("--request-extensions", argc, argv, argIndex, &gRequestedExtensions) ||
100 ParseFlag("--include-inactive-resources", argc, argv, argIndex,
101 &gIncludeInactiveResources);
102 }
103 } // namespace
104 } // namespace angle
105
106 using namespace angle;
107
ANGLEProcessPerfTestArgs(int * argc,char ** argv)108 void ANGLEProcessPerfTestArgs(int *argc, char **argv)
109 {
110 for (int argIndex = 1; argIndex < *argc;)
111 {
112 if (!PerfTestArg(argc, argv, argIndex))
113 {
114 argIndex++;
115 }
116 }
117
118 if (gRunToKeyFrame || gMaxStepsPerformed > 0)
119 {
120 // Ensure defaults were provided for params we're about to set
121 ASSERT(gTestTrials == kDefaultTestTrials && gTrialTimeSeconds == kDefaultTrialTimeSeconds);
122
123 gTestTrials = 1;
124 gTrialTimeSeconds = 36000;
125 }
126
127 if (gFixedTestTime != 0)
128 {
129 // Ensure defaults were provided for params we're about to set
130 ASSERT(gTrialTimeSeconds == kDefaultTrialTimeSeconds &&
131 gStepsPerTrial == kDefaultStepsPerTrial && gTestTrials == kDefaultTestTrials);
132
133 gTrialTimeSeconds = gFixedTestTime;
134 gStepsPerTrial = std::numeric_limits<int>::max();
135 gTestTrials = 1;
136 }
137
138 if (gFixedTestTimeWithWarmup != 0)
139 {
140 // Ensure defaults were provided for params we're about to set
141 ASSERT(gTrialTimeSeconds == kDefaultTrialTimeSeconds &&
142 gStepsPerTrial == kDefaultStepsPerTrial && gTestTrials == kDefaultTestTrials);
143
144 // This option is primarily useful for trace replays when you want to iterate once through
145 // the trace to warm caches, then run for a fixed amount of time. It is equivalent to:
146 // --trial-time X --steps-per-trial INF --trials 1 --warmup
147 gTrialTimeSeconds = gFixedTestTimeWithWarmup;
148 gStepsPerTrial = std::numeric_limits<int>::max();
149 gTestTrials = 1;
150 gWarmup = true;
151 }
152
153 if (gTrialTimeSeconds == 0)
154 {
155 gTrialTimeSeconds = 10;
156 }
157 }
158
ANGLEProcessTraceTestArgs(int * argc,char ** argv)159 void ANGLEProcessTraceTestArgs(int *argc, char **argv)
160 {
161 ANGLEProcessPerfTestArgs(argc, argv);
162
163 for (int argIndex = 1; argIndex < *argc;)
164 {
165 if (!TraceTestArg(argc, argv, argIndex))
166 {
167 argIndex++;
168 }
169 }
170
171 if (gScreenshotDir)
172 {
173 // implicitly set here but not when using kRenderTestOutputDir
174 gSaveScreenshots = true;
175 }
176
177 if (gRenderTestOutputDir)
178 {
179 gScreenshotDir = gRenderTestOutputDir;
180 }
181
182 if (gTraceTestValidation)
183 {
184 gTestTrials = 1;
185 gTrialTimeSeconds = 600;
186 }
187
188 if (kStandaloneBenchmark)
189 {
190 gVerboseLogging = true;
191 #if defined(ANGLE_PLATFORM_ANDROID)
192 gScreenshotDir = strdup((AndroidWindow::GetApplicationDirectory() + "/files").c_str());
193 #else
194 gScreenshotDir = ".";
195 #endif
196 gSaveScreenshots = true;
197 gUseANGLE = "vulkan";
198 }
199 }
200