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