1 //
2 // Copyright 2020 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 // Simple unit test suite that prints out system info as JSON.
7 //
8 // Example output for a Windows/NV machine:
9 //
10 // {
11 // "activeGPUIndex": 0,
12 // "isOptimus": false,
13 // "isMacSwitchable": false,
14 // "machineManufacturer": "",
15 // "machineModelVersion": "",
16 // "gpus": [
17 // {
18 // "vendorId": 4318,
19 // "deviceId": 7040,
20 // "driverVendor": "NVIDIA Corporation",
21 // "driverVersion": "452.6.0.0",
22 // "driverDate": "",
23 // "detailedDriverVersion": {
24 // "major": 452,
25 // "minor": 6,
26 // "subMinor": 0,
27 // "patch": 0
28 // }
29 // }
30 // ]
31 // }
32
33 #include "gpu_info_util/SystemInfo.h"
34
35 #include <gtest/gtest.h>
36 #include <rapidjson/document.h>
37 #include <rapidjson/prettywriter.h>
38 #include <rapidjson/stringbuffer.h>
39 #include <cstdlib>
40
41 #include "common/debug.h"
42 #if defined(ANGLE_ENABLE_VULKAN)
43 # include "gpu_info_util/SystemInfo_vulkan.h"
44 #endif // defined(ANGLE_ENABLE_VULKAN)
45
46 namespace js = rapidjson;
47
48 bool gFailedToFindGPU;
49
50 constexpr char kRenderTestOutputDir[] = "--render-test-output-dir=";
51
main(int argc,char ** argv)52 int main(int argc, char **argv)
53 {
54 angle::SystemInfo info;
55
56 bool useVulkan = false;
57 bool listTests = false;
58 bool useSwiftShader = false;
59 std::string output_dir;
60
61 for (int arg = 1; arg < argc; ++arg)
62 {
63 if (strcmp(argv[arg], "--vulkan") == 0)
64 {
65 useVulkan = true;
66 }
67 else if (strcmp(argv[arg], "--gtest_list_tests") == 0)
68 {
69 listTests = true;
70 }
71 else if (strcmp(argv[arg], "--swiftshader") == 0)
72 {
73 useSwiftShader = true;
74 }
75 else if (strstr(argv[arg], kRenderTestOutputDir))
76 {
77 output_dir = argv[arg] + strlen(kRenderTestOutputDir);
78 }
79 }
80
81 if (listTests)
82 {
83 testing::InitGoogleTest(&argc, argv);
84 return RUN_ALL_TESTS();
85 }
86
87 if (useVulkan)
88 {
89 #if defined(ANGLE_ENABLE_VULKAN)
90 angle::vk::ICD preferredICD =
91 useSwiftShader ? angle::vk::ICD::SwiftShader : angle::vk::ICD::Default;
92 angle::GetSystemInfoVulkanWithICD(&info, preferredICD);
93 #else
94 ANGLE_UNUSED_VARIABLE(useSwiftShader);
95 printf("Vulkan not supported.\n");
96 return EXIT_FAILURE;
97 #endif // defined(ANGLE_ENABLE_VULKAN)
98 }
99 else
100 {
101 angle::GetSystemInfo(&info);
102 }
103
104 if (info.gpus.empty())
105 {
106 gFailedToFindGPU = true;
107 }
108
109 js::Document doc;
110 doc.SetObject();
111
112 js::Document::AllocatorType &allocator = doc.GetAllocator();
113
114 doc.AddMember("activeGPUIndex", info.activeGPUIndex, allocator);
115 doc.AddMember("isOptimus", info.isOptimus, allocator);
116 doc.AddMember("isMacSwitchable", info.isMacSwitchable, allocator);
117
118 js::Value machineManufacturer;
119 machineManufacturer.SetString(info.machineManufacturer.c_str(), allocator);
120 doc.AddMember("machineManufacturer", machineManufacturer, allocator);
121
122 js::Value machineModelVersion;
123 machineModelVersion.SetString(info.machineModelVersion.c_str(), allocator);
124 doc.AddMember("machineModelVersion", machineModelVersion, allocator);
125
126 js::Value androidSdkLevel;
127 androidSdkLevel.SetInt(info.androidSdkLevel);
128 doc.AddMember("androidSdkLevel", androidSdkLevel, allocator);
129
130 js::Value gpus;
131 gpus.SetArray();
132
133 for (const angle::GPUDeviceInfo &gpu : info.gpus)
134 {
135 js::Value obj;
136 obj.SetObject();
137
138 obj.AddMember("vendorId", gpu.vendorId, allocator);
139 obj.AddMember("deviceId", gpu.deviceId, allocator);
140
141 js::Value driverVendor;
142 driverVendor.SetString(gpu.driverVendor.c_str(), allocator);
143 obj.AddMember("driverVendor", driverVendor, allocator);
144
145 js::Value driverVersion;
146 driverVersion.SetString(gpu.driverVersion.c_str(), allocator);
147 obj.AddMember("driverVersion", driverVersion, allocator);
148
149 js::Value driverDate;
150 driverDate.SetString(gpu.driverDate.c_str(), allocator);
151 obj.AddMember("driverDate", driverDate, allocator);
152
153 js::Value versionInfo;
154 versionInfo.SetObject();
155 versionInfo.AddMember("major", gpu.detailedDriverVersion.major, allocator);
156 versionInfo.AddMember("minor", gpu.detailedDriverVersion.minor, allocator);
157 versionInfo.AddMember("subMinor", gpu.detailedDriverVersion.subMinor, allocator);
158 versionInfo.AddMember("patch", gpu.detailedDriverVersion.patch, allocator);
159 obj.AddMember("detailedDriverVersion", versionInfo, allocator);
160
161 gpus.PushBack(obj, allocator);
162 }
163
164 doc.AddMember("gpus", gpus, allocator);
165
166 js::StringBuffer buffer;
167 js::PrettyWriter<js::StringBuffer> writer(buffer);
168 doc.Accept(writer);
169
170 const char *output = buffer.GetString();
171 printf("%s\n", output);
172
173 if (!output_dir.empty())
174 {
175 std::string outputFile = output_dir + "/angle_system_info.json";
176 FILE *fp = fopen(outputFile.c_str(), "w");
177 if (fp)
178 {
179 fwrite(output, sizeof(char), strlen(output), fp);
180 fclose(fp);
181 }
182 }
183
184 testing::InitGoogleTest(&argc, argv);
185 return RUN_ALL_TESTS();
186 }
187
TEST(ANGLE,SystemInfo)188 TEST(ANGLE, SystemInfo)
189 {
190 if (gFailedToFindGPU)
191 {
192 FAIL() << "Failed to find GPU info.";
193 }
194 }