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