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