Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/deqp_support/angle_deqp_gtest.cpp
1693 views
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
// angle_deqp_gtest:
7
// dEQP and GoogleTest integration logic. Calls through to the random
8
// order executor.
9
10
#include <stdint.h>
11
#include <array>
12
#include <fstream>
13
14
#include <gtest/gtest.h>
15
16
#include "angle_deqp_libtester.h"
17
#include "common/Optional.h"
18
#include "common/angleutils.h"
19
#include "common/debug.h"
20
#include "common/platform.h"
21
#include "common/string_utils.h"
22
#include "common/system_utils.h"
23
#include "platform/PlatformMethods.h"
24
#include "tests/test_utils/runner/TestSuite.h"
25
#include "util/OSWindow.h"
26
#include "util/test_utils.h"
27
28
namespace angle
29
{
30
namespace
31
{
32
#if !defined(NDEBUG)
33
constexpr bool kIsDebug = true;
34
#else
35
constexpr bool kIsDebug = false;
36
#endif // !defined(NDEBUG)
37
38
bool gGlobalError = false;
39
bool gExpectError = false;
40
bool gVerbose = false;
41
42
// Set this to true temporarily to enable image logging in release. Useful for diagnosing errors.
43
bool gLogImages = kIsDebug;
44
45
constexpr char kInfoTag[] = "*RESULT";
46
47
void HandlePlatformError(PlatformMethods *platform, const char *errorMessage)
48
{
49
if (!gExpectError)
50
{
51
FAIL() << errorMessage;
52
}
53
gGlobalError = true;
54
}
55
56
std::string DrawElementsToGoogleTestName(const std::string &dEQPName)
57
{
58
std::string gTestName = dEQPName.substr(dEQPName.find('.') + 1);
59
std::replace(gTestName.begin(), gTestName.end(), '.', '_');
60
61
// Occurs in some luminance tests
62
gTestName.erase(std::remove(gTestName.begin(), gTestName.end(), '-'), gTestName.end());
63
return gTestName;
64
}
65
66
// Relative to the ANGLE root folder.
67
constexpr char kCTSRootPath[] = "third_party/VK-GL-CTS/src/";
68
constexpr char kSupportPath[] = "src/tests/deqp_support/";
69
70
#define OPENGL_CTS_DIR(PATH) "external/openglcts/data/mustpass/gles/" PATH
71
72
const char *gCaseListFiles[] = {
73
OPENGL_CTS_DIR("aosp_mustpass/master/gles2-master.txt"),
74
OPENGL_CTS_DIR("aosp_mustpass/master/gles3-master.txt"),
75
OPENGL_CTS_DIR("aosp_mustpass/master/gles31-master.txt"),
76
"/android/cts/master/egl-master.txt",
77
OPENGL_CTS_DIR("khronos_mustpass/master/gles2-khr-master.txt"),
78
OPENGL_CTS_DIR("khronos_mustpass/master/gles3-khr-master.txt"),
79
OPENGL_CTS_DIR("khronos_mustpass/master/gles31-khr-master.txt"),
80
OPENGL_CTS_DIR("khronos_mustpass/master/gles32-khr-master.txt"),
81
OPENGL_CTS_DIR("aosp_mustpass/master/gles3-rotate-landscape.txt"),
82
OPENGL_CTS_DIR("aosp_mustpass/master/gles3-rotate-reverse-portrait.txt"),
83
OPENGL_CTS_DIR("aosp_mustpass/master/gles3-rotate-reverse-landscape.txt"),
84
OPENGL_CTS_DIR("aosp_mustpass/master/gles31-rotate-landscape.txt"),
85
OPENGL_CTS_DIR("aosp_mustpass/master/gles31-rotate-reverse-portrait.txt"),
86
OPENGL_CTS_DIR("aosp_mustpass/master/gles31-rotate-reverse-landscape.txt"),
87
};
88
89
#undef OPENGL_CTS_DIR
90
91
const char *gTestExpectationsFiles[] = {
92
"deqp_gles2_test_expectations.txt", "deqp_gles3_test_expectations.txt",
93
"deqp_gles31_test_expectations.txt", "deqp_egl_test_expectations.txt",
94
"deqp_khr_gles2_test_expectations.txt", "deqp_khr_gles3_test_expectations.txt",
95
"deqp_khr_gles31_test_expectations.txt", "deqp_khr_gles32_test_expectations.txt",
96
"deqp_gles3_rotate_test_expectations.txt", "deqp_gles3_rotate_test_expectations.txt",
97
"deqp_gles3_rotate_test_expectations.txt", "deqp_gles31_rotate_test_expectations.txt",
98
"deqp_gles31_rotate_test_expectations.txt", "deqp_gles31_rotate_test_expectations.txt",
99
};
100
101
using APIInfo = std::pair<const char *, GPUTestConfig::API>;
102
103
constexpr APIInfo kEGLDisplayAPIs[] = {
104
{"angle-d3d9", GPUTestConfig::kAPID3D9},
105
{"angle-d3d11", GPUTestConfig::kAPID3D11},
106
{"angle-d3d11-ref", GPUTestConfig::kAPID3D11},
107
{"angle-gl", GPUTestConfig::kAPIGLDesktop},
108
{"angle-gles", GPUTestConfig::kAPIGLES},
109
{"angle-metal", GPUTestConfig::kAPIMetal},
110
{"angle-null", GPUTestConfig::kAPIUnknown},
111
{"angle-swiftshader", GPUTestConfig::kAPISwiftShader},
112
{"angle-vulkan", GPUTestConfig::kAPIVulkan},
113
};
114
115
constexpr char kdEQPEGLString[] = "--deqp-egl-display-type=";
116
constexpr char kANGLEEGLString[] = "--use-angle=";
117
constexpr char kANGLEPreRotation[] = "--emulated-pre-rotation=";
118
constexpr char kANGLEDirectSPIRVGen[] = "--direct-spirv-gen";
119
constexpr char kdEQPCaseString[] = "--deqp-case=";
120
constexpr char kVerboseString[] = "--verbose";
121
constexpr char kRenderDocString[] = "--renderdoc";
122
123
std::array<char, 500> gCaseStringBuffer;
124
125
// For angle_deqp_gles3*_rotateN_tests, default gOptions.preRotation to N.
126
#if defined(ANGLE_DEQP_GLES3_ROTATE90_TESTS) || defined(ANGLE_DEQP_GLES31_ROTATE90_TESTS)
127
constexpr uint32_t kDefaultPreRotation = 90;
128
#elif defined(ANGLE_DEQP_GLES3_ROTATE180_TESTS) || defined(ANGLE_DEQP_GLES31_ROTATE180_TESTS)
129
constexpr uint32_t kDefaultPreRotation = 180;
130
#elif defined(ANGLE_DEQP_GLES3_ROTATE270_TESTS) || defined(ANGLE_DEQP_GLES31_ROTATE270_TESTS)
131
constexpr uint32_t kDefaultPreRotation = 270;
132
#else
133
constexpr uint32_t kDefaultPreRotation = 0;
134
#endif
135
136
const APIInfo *gInitAPI = nullptr;
137
dEQPOptions gOptions = {
138
kDefaultPreRotation, // preRotation
139
false, // enableDirectSPIRVGen
140
false, // enableRenderDocCapture
141
};
142
143
constexpr const char gdEQPEGLConfigNameString[] = "--deqp-gl-config-name=";
144
constexpr const char gdEQPLogImagesString[] = "--deqp-log-images=";
145
146
// Default the config to RGBA8
147
const char *gEGLConfigName = "rgba8888d24s8";
148
149
// Returns the default API for a platform.
150
const char *GetDefaultAPIName()
151
{
152
#if defined(ANGLE_PLATFORM_ANDROID) || defined(ANGLE_PLATFORM_LINUX) || \
153
defined(ANGLE_PLATFORM_WINDOWS)
154
return "angle-vulkan";
155
#elif defined(ANGLE_PLATFORM_APPLE)
156
return "angle-gl";
157
#else
158
# error Unknown platform.
159
#endif
160
}
161
162
const APIInfo *FindAPIInfo(const std::string &arg)
163
{
164
for (auto &displayAPI : kEGLDisplayAPIs)
165
{
166
if (arg == displayAPI.first)
167
{
168
return &displayAPI;
169
}
170
}
171
return nullptr;
172
}
173
174
const APIInfo *GetDefaultAPIInfo()
175
{
176
const APIInfo *defaultInfo = FindAPIInfo(GetDefaultAPIName());
177
ASSERT(defaultInfo);
178
return defaultInfo;
179
}
180
181
std::string GetTestStatLine(const std::string &key, const std::string &value)
182
{
183
return std::string(kInfoTag) + ": " + key + ": " + value + "\n";
184
}
185
186
// During the CaseList initialization we cannot use the GTEST FAIL macro to quit the program because
187
// the initialization is called outside of tests the first time.
188
void Die()
189
{
190
exit(EXIT_FAILURE);
191
}
192
193
Optional<std::string> FindFileFromPath(const char *dirPath, const char *filePath)
194
{
195
std::stringstream strstr;
196
strstr << dirPath << filePath;
197
std::string path = strstr.str();
198
199
constexpr size_t kMaxFoundPathLen = 1000;
200
char foundPath[kMaxFoundPathLen];
201
if (angle::FindTestDataPath(path.c_str(), foundPath, kMaxFoundPathLen))
202
{
203
return std::string(foundPath);
204
}
205
206
return Optional<std::string>::Invalid();
207
}
208
209
Optional<std::string> FindCaseListPath(size_t testModuleIndex)
210
{
211
return FindFileFromPath(kCTSRootPath, gCaseListFiles[testModuleIndex]);
212
}
213
214
Optional<std::string> FindTestExpectationsPath(size_t testModuleIndex)
215
{
216
return FindFileFromPath(kSupportPath, gTestExpectationsFiles[testModuleIndex]);
217
}
218
219
class dEQPCaseList
220
{
221
public:
222
dEQPCaseList(size_t testModuleIndex);
223
224
struct CaseInfo
225
{
226
CaseInfo(const std::string &dEQPName, const std::string &gTestName, int expectation)
227
: mDEQPName(dEQPName), mGTestName(gTestName), mExpectation(expectation)
228
{}
229
230
std::string mDEQPName;
231
std::string mGTestName;
232
int mExpectation;
233
};
234
235
void initialize();
236
237
const CaseInfo &getCaseInfo(size_t caseIndex) const
238
{
239
ASSERT(mInitialized);
240
ASSERT(caseIndex < mCaseInfoList.size());
241
return mCaseInfoList[caseIndex];
242
}
243
244
size_t numCases() const
245
{
246
ASSERT(mInitialized);
247
return mCaseInfoList.size();
248
}
249
250
private:
251
std::vector<CaseInfo> mCaseInfoList;
252
size_t mTestModuleIndex;
253
bool mInitialized = false;
254
};
255
256
dEQPCaseList::dEQPCaseList(size_t testModuleIndex) : mTestModuleIndex(testModuleIndex) {}
257
258
void dEQPCaseList::initialize()
259
{
260
if (mInitialized)
261
{
262
return;
263
}
264
265
mInitialized = true;
266
267
Optional<std::string> caseListPath = FindCaseListPath(mTestModuleIndex);
268
if (!caseListPath.valid())
269
{
270
std::cerr << "Failed to find case list file." << std::endl;
271
Die();
272
}
273
274
Optional<std::string> testExpectationsPath = FindTestExpectationsPath(mTestModuleIndex);
275
if (!testExpectationsPath.valid())
276
{
277
std::cerr << "Failed to find test expectations file." << std::endl;
278
Die();
279
}
280
281
GPUTestConfig::API api = GetDefaultAPIInfo()->second;
282
// Set the API from the command line, or using the default platform API.
283
if (gInitAPI)
284
{
285
api = gInitAPI->second;
286
}
287
288
GPUTestConfig testConfig =
289
GPUTestConfig(api, gOptions.preRotation, gOptions.enableDirectSPIRVGen);
290
291
#if !defined(ANGLE_PLATFORM_ANDROID)
292
// Note: These prints mess up parsing of test list when running on Android.
293
std::cout << "Using test config with:" << std::endl;
294
for (uint32_t condition : testConfig.getConditions())
295
{
296
const char *name = GetConditionName(condition);
297
if (name != nullptr)
298
{
299
std::cout << " " << name << std::endl;
300
}
301
}
302
#endif
303
304
TestSuite *testSuite = TestSuite::GetInstance();
305
306
if (!testSuite->loadTestExpectationsFromFileWithConfig(testConfig,
307
testExpectationsPath.value()))
308
{
309
Die();
310
}
311
312
std::ifstream caseListStream(caseListPath.value());
313
if (caseListStream.fail())
314
{
315
std::cerr << "Failed to load the case list." << std::endl;
316
Die();
317
}
318
319
while (!caseListStream.eof())
320
{
321
std::string inString;
322
std::getline(caseListStream, inString);
323
324
std::string dEQPName = TrimString(inString, kWhitespaceASCII);
325
if (dEQPName.empty())
326
continue;
327
std::string gTestName = DrawElementsToGoogleTestName(dEQPName);
328
if (gTestName.empty())
329
continue;
330
331
int expectation = testSuite->getTestExpectation(dEQPName);
332
mCaseInfoList.push_back(CaseInfo(dEQPName, gTestName, expectation));
333
}
334
335
if (testSuite->logAnyUnusedTestExpectations())
336
{
337
Die();
338
}
339
}
340
341
template <size_t TestModuleIndex>
342
class dEQPTest : public testing::TestWithParam<size_t>
343
{
344
public:
345
static testing::internal::ParamGenerator<size_t> GetTestingRange()
346
{
347
return testing::Range<size_t>(0, GetCaseList().numCases());
348
}
349
350
static std::string GetCaseGTestName(size_t caseIndex)
351
{
352
const auto &caseInfo = GetCaseList().getCaseInfo(caseIndex);
353
return caseInfo.mGTestName;
354
}
355
356
static const dEQPCaseList &GetCaseList()
357
{
358
static dEQPCaseList sCaseList(TestModuleIndex);
359
sCaseList.initialize();
360
return sCaseList;
361
}
362
363
static void SetUpTestCase();
364
static void TearDownTestCase();
365
366
protected:
367
void runTest() const
368
{
369
if (sTestExceptionCount > 1)
370
{
371
std::cout << "Too many exceptions, skipping all remaining tests." << std::endl;
372
return;
373
}
374
375
const auto &caseInfo = GetCaseList().getCaseInfo(GetParam());
376
std::cout << caseInfo.mDEQPName << std::endl;
377
378
// Tests that crash exit the harness before collecting the result. To tally the number of
379
// crashed tests we track how many tests we "tried" to run.
380
sTestCount++;
381
382
if (caseInfo.mExpectation == GPUTestExpectationsParser::kGpuTestSkip)
383
{
384
sSkippedTestCount++;
385
std::cout << "Test skipped.\n";
386
return;
387
}
388
389
TestSuite *testSuite = TestSuite::GetInstance();
390
testSuite->maybeUpdateTestTimeout(caseInfo.mExpectation);
391
392
gExpectError = (caseInfo.mExpectation != GPUTestExpectationsParser::kGpuTestPass);
393
dEQPTestResult result = deqp_libtester_run(caseInfo.mDEQPName.c_str());
394
395
bool testSucceeded = countTestResultAndReturnSuccess(result);
396
397
// Check the global error flag for unexpected platform errors.
398
if (gGlobalError)
399
{
400
testSucceeded = false;
401
gGlobalError = false;
402
}
403
404
if (caseInfo.mExpectation == GPUTestExpectationsParser::kGpuTestPass)
405
{
406
EXPECT_TRUE(testSucceeded);
407
408
if (!testSucceeded)
409
{
410
sUnexpectedFailed.push_back(caseInfo.mDEQPName);
411
}
412
}
413
else if (testSucceeded)
414
{
415
std::cout << "Test expected to fail but passed!" << std::endl;
416
sUnexpectedPasses.push_back(caseInfo.mDEQPName);
417
}
418
}
419
420
bool countTestResultAndReturnSuccess(dEQPTestResult result) const
421
{
422
switch (result)
423
{
424
case dEQPTestResult::Pass:
425
sPassedTestCount++;
426
return true;
427
case dEQPTestResult::Fail:
428
sFailedTestCount++;
429
return false;
430
case dEQPTestResult::NotSupported:
431
sNotSupportedTestCount++;
432
return true;
433
case dEQPTestResult::Exception:
434
sTestExceptionCount++;
435
return false;
436
default:
437
std::cerr << "Unexpected test result code: " << static_cast<int>(result) << "\n";
438
return false;
439
}
440
}
441
442
static void PrintTestStats()
443
{
444
uint32_t crashedCount =
445
sTestCount - (sPassedTestCount + sFailedTestCount + sNotSupportedTestCount +
446
sTestExceptionCount + sSkippedTestCount);
447
448
std::cout << GetTestStatLine("Total", std::to_string(sTestCount));
449
std::cout << GetTestStatLine("Passed", std::to_string(sPassedTestCount));
450
std::cout << GetTestStatLine("Failed", std::to_string(sFailedTestCount));
451
std::cout << GetTestStatLine("Skipped", std::to_string(sSkippedTestCount));
452
std::cout << GetTestStatLine("Not Supported", std::to_string(sNotSupportedTestCount));
453
std::cout << GetTestStatLine("Exception", std::to_string(sTestExceptionCount));
454
std::cout << GetTestStatLine("Crashed", std::to_string(crashedCount));
455
456
if (!sUnexpectedPasses.empty())
457
{
458
std::cout << GetTestStatLine("Unexpected Passed Count",
459
std::to_string(sUnexpectedPasses.size()));
460
for (const std::string &testName : sUnexpectedPasses)
461
{
462
std::cout << GetTestStatLine("Unexpected Passed Tests", testName);
463
}
464
}
465
466
if (!sUnexpectedFailed.empty())
467
{
468
std::cout << GetTestStatLine("Unexpected Failed Count",
469
std::to_string(sUnexpectedFailed.size()));
470
for (const std::string &testName : sUnexpectedFailed)
471
{
472
std::cout << GetTestStatLine("Unexpected Failed Tests", testName);
473
}
474
}
475
}
476
477
static uint32_t sTestCount;
478
static uint32_t sPassedTestCount;
479
static uint32_t sFailedTestCount;
480
static uint32_t sTestExceptionCount;
481
static uint32_t sNotSupportedTestCount;
482
static uint32_t sSkippedTestCount;
483
484
static std::vector<std::string> sUnexpectedFailed;
485
static std::vector<std::string> sUnexpectedPasses;
486
};
487
488
template <size_t TestModuleIndex>
489
uint32_t dEQPTest<TestModuleIndex>::sTestCount = 0;
490
template <size_t TestModuleIndex>
491
uint32_t dEQPTest<TestModuleIndex>::sPassedTestCount = 0;
492
template <size_t TestModuleIndex>
493
uint32_t dEQPTest<TestModuleIndex>::sFailedTestCount = 0;
494
template <size_t TestModuleIndex>
495
uint32_t dEQPTest<TestModuleIndex>::sTestExceptionCount = 0;
496
template <size_t TestModuleIndex>
497
uint32_t dEQPTest<TestModuleIndex>::sNotSupportedTestCount = 0;
498
template <size_t TestModuleIndex>
499
uint32_t dEQPTest<TestModuleIndex>::sSkippedTestCount = 0;
500
template <size_t TestModuleIndex>
501
std::vector<std::string> dEQPTest<TestModuleIndex>::sUnexpectedFailed;
502
template <size_t TestModuleIndex>
503
std::vector<std::string> dEQPTest<TestModuleIndex>::sUnexpectedPasses;
504
505
// static
506
template <size_t TestModuleIndex>
507
void dEQPTest<TestModuleIndex>::SetUpTestCase()
508
{
509
sPassedTestCount = 0;
510
sFailedTestCount = 0;
511
sNotSupportedTestCount = 0;
512
sTestExceptionCount = 0;
513
sTestCount = 0;
514
sSkippedTestCount = 0;
515
sUnexpectedPasses.clear();
516
sUnexpectedFailed.clear();
517
518
std::vector<const char *> argv;
519
520
// Reserve one argument for the binary name.
521
argv.push_back("");
522
523
// Add init api.
524
const char *targetApi = gInitAPI ? gInitAPI->first : GetDefaultAPIName();
525
std::string apiArgString = std::string(kdEQPEGLString) + targetApi;
526
argv.push_back(apiArgString.c_str());
527
528
// Add config name
529
const char *targetConfigName = gEGLConfigName;
530
std::string configArgString = std::string(gdEQPEGLConfigNameString) + targetConfigName;
531
argv.push_back(configArgString.c_str());
532
533
// Hide SwiftShader window to prevent a race with Xvfb causing hangs on test bots
534
if (gInitAPI && gInitAPI->second == GPUTestConfig::kAPISwiftShader)
535
{
536
argv.push_back("--deqp-visibility=hidden");
537
}
538
539
TestSuite *testSuite = TestSuite::GetInstance();
540
541
std::stringstream logNameStream;
542
logNameStream << "TestResults";
543
if (testSuite->getBatchId() != -1)
544
{
545
logNameStream << "-Batch" << std::setfill('0') << std::setw(3) << testSuite->getBatchId();
546
}
547
logNameStream << ".qpa";
548
549
std::stringstream logArgStream;
550
logArgStream << "--deqp-log-filename=" << testSuite->addTestArtifact(logNameStream.str());
551
552
std::string logNameString = logArgStream.str();
553
argv.push_back(logNameString.c_str());
554
555
if (!gLogImages)
556
{
557
argv.push_back("--deqp-log-images=disable");
558
}
559
560
// Flushing during multi-process execution punishes HDDs. http://anglebug.com/5157
561
if (testSuite->getBatchId() != -1)
562
{
563
argv.push_back("--deqp-log-flush=disable");
564
}
565
566
// Init the platform.
567
if (!deqp_libtester_init_platform(static_cast<int>(argv.size()), argv.data(),
568
reinterpret_cast<void *>(&HandlePlatformError), gOptions))
569
{
570
std::cout << "Aborting test due to dEQP initialization error." << std::endl;
571
exit(1);
572
}
573
}
574
575
// static
576
template <size_t TestModuleIndex>
577
void dEQPTest<TestModuleIndex>::TearDownTestCase()
578
{
579
PrintTestStats();
580
deqp_libtester_shutdown_platform();
581
}
582
583
#define ANGLE_INSTANTIATE_DEQP_TEST_CASE(API, N) \
584
class dEQP : public dEQPTest<N> \
585
{}; \
586
TEST_P(dEQP, API) { runTest(); } \
587
\
588
INSTANTIATE_TEST_SUITE_P(, dEQP, dEQP::GetTestingRange(), \
589
[](const testing::TestParamInfo<size_t> &info) { \
590
return dEQP::GetCaseGTestName(info.param); \
591
})
592
593
#ifdef ANGLE_DEQP_GLES2_TESTS
594
ANGLE_INSTANTIATE_DEQP_TEST_CASE(GLES2, 0);
595
#endif
596
597
#ifdef ANGLE_DEQP_GLES3_TESTS
598
ANGLE_INSTANTIATE_DEQP_TEST_CASE(GLES3, 1);
599
#endif
600
601
#ifdef ANGLE_DEQP_GLES31_TESTS
602
ANGLE_INSTANTIATE_DEQP_TEST_CASE(GLES31, 2);
603
#endif
604
605
#ifdef ANGLE_DEQP_EGL_TESTS
606
ANGLE_INSTANTIATE_DEQP_TEST_CASE(EGL, 3);
607
#endif
608
609
#ifdef ANGLE_DEQP_KHR_GLES2_TESTS
610
ANGLE_INSTANTIATE_DEQP_TEST_CASE(KHR_GLES2, 4);
611
#endif
612
613
#ifdef ANGLE_DEQP_KHR_GLES3_TESTS
614
ANGLE_INSTANTIATE_DEQP_TEST_CASE(KHR_GLES3, 5);
615
#endif
616
617
#ifdef ANGLE_DEQP_KHR_GLES31_TESTS
618
ANGLE_INSTANTIATE_DEQP_TEST_CASE(KHR_GLES31, 6);
619
#endif
620
621
#ifdef ANGLE_DEQP_KHR_GLES32_TESTS
622
ANGLE_INSTANTIATE_DEQP_TEST_CASE(KHR_GLES32, 7);
623
#endif
624
625
#ifdef ANGLE_DEQP_GLES3_ROTATE90_TESTS
626
ANGLE_INSTANTIATE_DEQP_TEST_CASE(GLES3_ROTATE90, 8);
627
#endif
628
629
#ifdef ANGLE_DEQP_GLES3_ROTATE180_TESTS
630
ANGLE_INSTANTIATE_DEQP_TEST_CASE(GLES3_ROTATE180, 9);
631
#endif
632
633
#ifdef ANGLE_DEQP_GLES3_ROTATE270_TESTS
634
ANGLE_INSTANTIATE_DEQP_TEST_CASE(GLES3_ROTATE270, 10);
635
#endif
636
637
#ifdef ANGLE_DEQP_GLES31_ROTATE90_TESTS
638
ANGLE_INSTANTIATE_DEQP_TEST_CASE(GLES31_ROTATE90, 11);
639
#endif
640
641
#ifdef ANGLE_DEQP_GLES31_ROTATE180_TESTS
642
ANGLE_INSTANTIATE_DEQP_TEST_CASE(GLES31_ROTATE180, 12);
643
#endif
644
645
#ifdef ANGLE_DEQP_GLES31_ROTATE270_TESTS
646
ANGLE_INSTANTIATE_DEQP_TEST_CASE(GLES31_ROTATE270, 13);
647
#endif
648
649
void HandleDisplayType(const char *displayTypeString)
650
{
651
std::stringstream argStream;
652
653
if (gInitAPI)
654
{
655
std::cout << "Cannot specify two EGL displays!" << std::endl;
656
exit(1);
657
}
658
659
if (strncmp(displayTypeString, "angle-", strlen("angle-")) != 0)
660
{
661
argStream << "angle-";
662
}
663
664
argStream << displayTypeString;
665
std::string arg = argStream.str();
666
667
gInitAPI = FindAPIInfo(arg);
668
669
if (!gInitAPI)
670
{
671
std::cout << "Unknown ANGLE back-end API: " << displayTypeString << std::endl;
672
exit(1);
673
}
674
}
675
676
void HandlePreRotation(const char *preRotationString)
677
{
678
std::istringstream argStream(preRotationString);
679
680
uint32_t preRotation = 0;
681
argStream >> preRotation;
682
683
if (!argStream ||
684
(preRotation != 0 && preRotation != 90 && preRotation != 180 && preRotation != 270))
685
{
686
std::cout << "Invalid PreRotation '" << preRotationString
687
<< "'; must be either 0, 90, 180 or 270" << std::endl;
688
exit(1);
689
}
690
691
gOptions.preRotation = preRotation;
692
}
693
694
void HandleEGLConfigName(const char *configNameString)
695
{
696
gEGLConfigName = configNameString;
697
}
698
699
// The --deqp-case flag takes a case expression that is parsed into a --gtest_filter. It converts
700
// the "dEQP" style names (functional.thing.*) into "GoogleTest" style names (functional_thing_*).
701
// Currently it does not handle multiple tests and multiple filters in different arguments.
702
void HandleCaseName(const char *caseString, int *argc, int argIndex, char **argv)
703
{
704
std::string googleTestName = DrawElementsToGoogleTestName(caseString);
705
gCaseStringBuffer.fill(0);
706
int bytesWritten = snprintf(gCaseStringBuffer.data(), gCaseStringBuffer.size() - 1,
707
"--gtest_filter=*%s", googleTestName.c_str());
708
if (bytesWritten <= 0 || static_cast<size_t>(bytesWritten) >= gCaseStringBuffer.size() - 1)
709
{
710
std::cout << "Error parsing test case string: " << caseString;
711
exit(1);
712
}
713
714
argv[argIndex] = gCaseStringBuffer.data();
715
}
716
717
void HandleLogImages(const char *logImagesString)
718
{
719
if (strcmp(logImagesString, "enable") == 0)
720
{
721
gLogImages = true;
722
}
723
else if (strcmp(logImagesString, "disable") == 0)
724
{
725
gLogImages = false;
726
}
727
else
728
{
729
std::cout << "Error parsing log images setting. Use enable/disable.";
730
exit(1);
731
}
732
}
733
} // anonymous namespace
734
735
// Called from main() to process command-line arguments.
736
void InitTestHarness(int *argc, char **argv)
737
{
738
int argIndex = 0;
739
while (argIndex < *argc)
740
{
741
if (strncmp(argv[argIndex], kdEQPEGLString, strlen(kdEQPEGLString)) == 0)
742
{
743
HandleDisplayType(argv[argIndex] + strlen(kdEQPEGLString));
744
}
745
else if (strncmp(argv[argIndex], kANGLEEGLString, strlen(kANGLEEGLString)) == 0)
746
{
747
HandleDisplayType(argv[argIndex] + strlen(kANGLEEGLString));
748
}
749
else if (strncmp(argv[argIndex], kANGLEPreRotation, strlen(kANGLEPreRotation)) == 0)
750
{
751
HandlePreRotation(argv[argIndex] + strlen(kANGLEPreRotation));
752
}
753
else if (strncmp(argv[argIndex], kANGLEDirectSPIRVGen, strlen(kANGLEDirectSPIRVGen)) == 0)
754
{
755
gOptions.enableDirectSPIRVGen = true;
756
}
757
else if (strncmp(argv[argIndex], gdEQPEGLConfigNameString,
758
strlen(gdEQPEGLConfigNameString)) == 0)
759
{
760
HandleEGLConfigName(argv[argIndex] + strlen(gdEQPEGLConfigNameString));
761
}
762
else if (strncmp(argv[argIndex], kdEQPCaseString, strlen(kdEQPCaseString)) == 0)
763
{
764
HandleCaseName(argv[argIndex] + strlen(kdEQPCaseString), argc, argIndex, argv);
765
}
766
else if (strncmp(argv[argIndex], kVerboseString, strlen(kVerboseString)) == 0 ||
767
strcmp(argv[argIndex], "-v") == 0)
768
{
769
gVerbose = true;
770
}
771
else if (strncmp(argv[argIndex], gdEQPLogImagesString, strlen(gdEQPLogImagesString)) == 0)
772
{
773
HandleLogImages(argv[argIndex] + strlen(gdEQPLogImagesString));
774
}
775
else if (strncmp(argv[argIndex], kRenderDocString, strlen(kRenderDocString)) == 0)
776
{
777
gOptions.enableRenderDocCapture = true;
778
}
779
argIndex++;
780
}
781
782
GPUTestConfig::API api = GetDefaultAPIInfo()->second;
783
if (gInitAPI)
784
{
785
api = gInitAPI->second;
786
}
787
if (gOptions.preRotation != 0 && api != GPUTestConfig::kAPIVulkan &&
788
api != GPUTestConfig::kAPISwiftShader)
789
{
790
std::cout << "PreRotation is only supported on Vulkan" << std::endl;
791
exit(1);
792
}
793
if (gOptions.enableDirectSPIRVGen != 0 && api != GPUTestConfig::kAPIVulkan &&
794
api != GPUTestConfig::kAPISwiftShader)
795
{
796
std::cout << "SPIR-V generation is only relevant to Vulkan" << std::endl;
797
exit(1);
798
}
799
}
800
} // namespace angle
801
802