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