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