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 // Feature.h: Definition of structs to hold feature/workaround information.
7 //
8
9 #ifndef ANGLE_PLATFORM_FEATURE_H_
10 #define ANGLE_PLATFORM_FEATURE_H_
11
12 #include <map>
13 #include <string>
14 #include <vector>
15
16 #define ANGLE_FEATURE_CONDITION(set, feature, cond) \
17 do \
18 { \
19 (set)->feature.enabled = cond; \
20 (set)->feature.condition = ANGLE_STRINGIFY(cond); \
21 } while (0)
22
23 namespace angle
24 {
25
26 enum class FeatureCategory
27 {
28 FrontendWorkarounds,
29 OpenGLWorkarounds,
30 D3DWorkarounds,
31 D3DCompilerWorkarounds,
32 VulkanWorkarounds,
33 VulkanFeatures,
34 MetalFeatures,
35 };
36
37 constexpr char kFeatureCategoryFrontendWorkarounds[] = "Frontend workarounds";
38 constexpr char kFeatureCategoryOpenGLWorkarounds[] = "OpenGL workarounds";
39 constexpr char kFeatureCategoryD3DWorkarounds[] = "D3D workarounds";
40 constexpr char kFeatureCategoryD3DCompilerWorkarounds[] = "D3D compiler workarounds";
41 constexpr char kFeatureCategoryVulkanWorkarounds[] = "Vulkan workarounds";
42 constexpr char kFeatureCategoryVulkanFeatures[] = "Vulkan features";
43 constexpr char kFeatureCategoryMetalFeatures[] = "Metal features";
44 constexpr char kFeatureCategoryUnknown[] = "Unknown";
45
FeatureCategoryToString(const FeatureCategory & fc)46 inline const char *FeatureCategoryToString(const FeatureCategory &fc)
47 {
48 switch (fc)
49 {
50 case FeatureCategory::FrontendWorkarounds:
51 return kFeatureCategoryFrontendWorkarounds;
52 break;
53
54 case FeatureCategory::OpenGLWorkarounds:
55 return kFeatureCategoryOpenGLWorkarounds;
56 break;
57
58 case FeatureCategory::D3DWorkarounds:
59 return kFeatureCategoryD3DWorkarounds;
60 break;
61
62 case FeatureCategory::D3DCompilerWorkarounds:
63 return kFeatureCategoryD3DCompilerWorkarounds;
64 break;
65
66 case FeatureCategory::VulkanWorkarounds:
67 return kFeatureCategoryVulkanWorkarounds;
68 break;
69
70 case FeatureCategory::VulkanFeatures:
71 return kFeatureCategoryVulkanFeatures;
72 break;
73
74 case FeatureCategory::MetalFeatures:
75 return kFeatureCategoryMetalFeatures;
76 break;
77
78 default:
79 return kFeatureCategoryUnknown;
80 break;
81 }
82 }
83
84 constexpr char kFeatureStatusEnabled[] = "enabled";
85 constexpr char kFeatureStatusDisabled[] = "disabled";
86
FeatureStatusToString(const bool & status)87 inline const char *FeatureStatusToString(const bool &status)
88 {
89 if (status)
90 {
91 return kFeatureStatusEnabled;
92 }
93 return kFeatureStatusDisabled;
94 }
95
96 struct Feature;
97
98 using FeatureMap = std::map<std::string, Feature *>;
99 using FeatureList = std::vector<const Feature *>;
100
101 struct Feature
102 {
103 Feature(const Feature &other);
104 Feature(const char *name,
105 const FeatureCategory &category,
106 const char *description,
107 FeatureMap *const mapPtr,
108 const char *bug);
109 ~Feature();
110
111 // The name of the workaround, lowercase, camel_case
112 const char *const name;
113
114 // The category that the workaround belongs to. Eg. "Vulkan workarounds"
115 const FeatureCategory category;
116
117 // A short description to be read by the user.
118 const char *const description;
119
120 // A link to the bug, if any
121 const char *const bug;
122
123 // Whether the workaround is enabled or not. Determined by heuristics like vendor ID and
124 // version, but may be overriden to any value.
125 bool enabled = false;
126
127 // A stingified version of the condition used to set 'enabled'. ie "IsNvidia() && IsApple()"
128 const char *condition;
129 };
130
131 inline Feature::Feature(const Feature &other) = default;
132 inline Feature::Feature(const char *name,
133 const FeatureCategory &category,
134 const char *description,
135 FeatureMap *const mapPtr,
136 const char *bug = "")
name(name)137 : name(name),
138 category(category),
139 description(description),
140 bug(bug),
141 enabled(false),
142 condition("")
143 {
144 if (mapPtr != nullptr)
145 {
146 (*mapPtr)[std::string(name)] = this;
147 }
148 }
149
150 inline Feature::~Feature() = default;
151
152 struct FeatureSetBase
153 {
154 public:
155 FeatureSetBase();
156 ~FeatureSetBase();
157
158 private:
159 // Non-copyable
160 FeatureSetBase(const FeatureSetBase &other) = delete;
161 FeatureSetBase &operator=(const FeatureSetBase &other) = delete;
162
163 protected:
164 FeatureMap members = FeatureMap();
165
166 public:
overrideFeaturesFeatureSetBase167 void overrideFeatures(const std::vector<std::string> &feature_names, const bool enabled)
168 {
169 for (const std::string &name : feature_names)
170 {
171 if (members.find(name) != members.end())
172 {
173 members[name]->enabled = enabled;
174 }
175 }
176 }
177
populateFeatureListFeatureSetBase178 void populateFeatureList(FeatureList *features) const
179 {
180 for (FeatureMap::const_iterator it = members.begin(); it != members.end(); it++)
181 {
182 features->push_back(it->second);
183 }
184 }
185 };
186
187 inline FeatureSetBase::FeatureSetBase() = default;
188 inline FeatureSetBase::~FeatureSetBase() = default;
189
190 } // namespace angle
191
192 #endif // ANGLE_PLATFORM_WORKAROUND_H_
193