1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
gpu / config / gpu_blocklist_unittest.cc [blame]
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <vector>
#include "gpu/config/gpu_blocklist.h"
#include "gpu/config/gpu_driver_bug_list_autogen.h"
#include "gpu/config/gpu_feature_type.h"
#include "gpu/config/gpu_info.h"
#include "gpu/config/software_rendering_list_autogen.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/re2/src/re2/re2.h"
namespace gpu {
class GpuBlocklistTest : public testing::Test {
public:
GpuBlocklistTest() = default;
~GpuBlocklistTest() override = default;
const GPUInfo& gpu_info() const { return gpu_info_; }
void RunFeatureTest(GpuFeatureType feature_type) {
const std::array<const int, 1> kFeatureListForEntry1 = {feature_type};
const GpuControlList::Device kDevicesForEntry1[1] = {{0x0640, 0x0}};
const std::array<GpuControlList::Entry, 1> kTestEntries = {{{
1, // id
"Test entry", // description
base::span(kFeatureListForEntry1), // features
base::span<const char* const>(), // DisabledExtensions
base::span<const char* const>(), // DisabledWebGLExtensions
base::span<const uint32_t>(), // CrBugs
{
GpuControlList::kOsMacosx, // os_type
{GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical,
GpuControlList::kVersionSchemaCommon, nullptr,
nullptr}, // os_version
0x10de, // vendor_id
base::span(kDevicesForEntry1), // Devices
GpuControlList::kMultiGpuCategoryAny, // multi_gpu_category
GpuControlList::kMultiGpuStyleNone, // multi_gpu_style
nullptr, // driver info
nullptr, // GL strings
nullptr, // machine model info
nullptr, // Intel conditions
nullptr, // more conditions
},
base::span<GpuControlList::Conditions>(), // exceptions
}}};
std::unique_ptr<GpuBlocklist> blocklist =
GpuBlocklist::Create(kTestEntries);
std::set<int> type =
blocklist->MakeDecision(GpuBlocklist::kOsMacosx, "10.12.3", gpu_info());
EXPECT_EQ(1u, type.size());
EXPECT_EQ(1u, type.count(feature_type));
}
protected:
void SetUp() override {
gpu_info_.gpu.vendor_id = 0x10de;
gpu_info_.gpu.device_id = 0x0640;
gpu_info_.gpu.driver_vendor = "NVIDIA";
gpu_info_.gpu.driver_version = "1.6.18";
gpu_info_.machine_model_name = "MacBookPro";
gpu_info_.machine_model_version = "7.1";
gpu_info_.gl_vendor = "NVIDIA Corporation";
gpu_info_.gl_renderer = "NVIDIA GeForce GT 120 OpenGL Engine";
}
private:
GPUInfo gpu_info_;
};
#define GPU_BLOCKLIST_FEATURE_TEST(test_name, feature_type) \
TEST_F(GpuBlocklistTest, test_name) { RunFeatureTest(feature_type); }
GPU_BLOCKLIST_FEATURE_TEST(Accelerated2DCanvas,
GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)
GPU_BLOCKLIST_FEATURE_TEST(AcceleratedWebGL, GPU_FEATURE_TYPE_ACCELERATED_WEBGL)
GPU_BLOCKLIST_FEATURE_TEST(AcceleratedVideoDecode,
GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE)
GPU_BLOCKLIST_FEATURE_TEST(AcceleratedVideoEncode,
GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE)
GPU_BLOCKLIST_FEATURE_TEST(GpuRasterization,
GPU_FEATURE_TYPE_GPU_TILE_RASTERIZATION)
GPU_BLOCKLIST_FEATURE_TEST(WebGL2, GPU_FEATURE_TYPE_ACCELERATED_WEBGL2)
GPU_BLOCKLIST_FEATURE_TEST(GL, GPU_FEATURE_TYPE_ACCELERATED_GL)
GPU_BLOCKLIST_FEATURE_TEST(Vulkan, GPU_FEATURE_TYPE_VULKAN)
GPU_BLOCKLIST_FEATURE_TEST(AcceleratedWebGPU,
GPU_FEATURE_TYPE_ACCELERATED_WEBGPU)
GPU_BLOCKLIST_FEATURE_TEST(SkiaGraphite, GPU_FEATURE_TYPE_SKIA_GRAPHITE)
GPU_BLOCKLIST_FEATURE_TEST(WebNN, GPU_FEATURE_TYPE_WEBNN)
// Test for invariant "Assume the newly last added entry has the largest ID".
// See GpuControlList::GpuControlList.
// It checks software_rendering_list.json
TEST_F(GpuBlocklistTest, TestBlocklistIsValid) {
std::unique_ptr<GpuBlocklist> list(GpuBlocklist::Create());
uint32_t max_entry_id = list->max_entry_id();
std::vector<uint32_t> indices(list->num_entries());
int current = 0;
std::generate(indices.begin(), indices.end(),
[¤t]() { return current++; });
auto entries = list->GetEntryIDsFromIndices(indices);
auto real_max_entry_id = *std::max_element(entries.begin(), entries.end());
EXPECT_EQ(real_max_entry_id, max_entry_id);
}
void TestBlockList(base::span<const GpuControlList::Entry> entries) {
for (const auto& entry : entries) {
if (const auto* gl_strings = entry.conditions.gl_strings) {
if (gl_strings->gl_vendor) {
EXPECT_TRUE(RE2(gl_strings->gl_vendor).ok())
<< "gl_vendor=" << gl_strings->gl_vendor;
}
if (gl_strings->gl_renderer) {
EXPECT_TRUE(RE2(gl_strings->gl_renderer).ok())
<< "gl_renderer=" << gl_strings->gl_renderer;
}
if (gl_strings->gl_extensions) {
EXPECT_TRUE(RE2(gl_strings->gl_extensions).ok())
<< "gl_extensions=" << gl_strings->gl_extensions;
}
if (gl_strings->gl_version) {
EXPECT_TRUE(RE2(gl_strings->gl_version).ok())
<< "gl_version=" << gl_strings->gl_version;
}
}
for (const auto& conditions : entry.exceptions) {
if (const auto* gl_strings = conditions.gl_strings) {
if (gl_strings->gl_vendor) {
EXPECT_TRUE(RE2(gl_strings->gl_vendor).ok())
<< "gl_vendor=" << gl_strings->gl_vendor;
}
if (gl_strings->gl_renderer) {
EXPECT_TRUE(RE2(gl_strings->gl_renderer).ok())
<< "gl_renderer=" << gl_strings->gl_renderer;
}
if (gl_strings->gl_extensions) {
EXPECT_TRUE(RE2(gl_strings->gl_extensions).ok())
<< "gl_extensions=" << gl_strings->gl_extensions;
}
if (gl_strings->gl_version) {
EXPECT_TRUE(RE2(gl_strings->gl_version).ok())
<< "gl_version=" << gl_strings->gl_version;
}
}
}
}
}
// It checks software_rendering_list.json
TEST_F(GpuBlocklistTest, VerifyGLStrings) {
TestBlockList(GetSoftwareRenderingListEntries());
TestBlockList(GetGpuDriverBugListEntries());
}
} // namespace gpu