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