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