1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // Feature.h: Definition of structs to hold feature/workaround information.
7*8975f5c5SAndroid Build Coastguard Worker //
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #ifndef ANGLE_PLATFORM_FEATURE_H_
10*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_PLATFORM_FEATURE_H_
11*8975f5c5SAndroid Build Coastguard Worker
12*8975f5c5SAndroid Build Coastguard Worker #include <map>
13*8975f5c5SAndroid Build Coastguard Worker #include <string>
14*8975f5c5SAndroid Build Coastguard Worker #include <vector>
15*8975f5c5SAndroid Build Coastguard Worker
16*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_FEATURE_CONDITION(set, feature, cond) \
17*8975f5c5SAndroid Build Coastguard Worker do \
18*8975f5c5SAndroid Build Coastguard Worker { \
19*8975f5c5SAndroid Build Coastguard Worker if (!(set)->feature.hasOverride) \
20*8975f5c5SAndroid Build Coastguard Worker { \
21*8975f5c5SAndroid Build Coastguard Worker (set)->feature.enabled = cond; \
22*8975f5c5SAndroid Build Coastguard Worker } \
23*8975f5c5SAndroid Build Coastguard Worker } while (0)
24*8975f5c5SAndroid Build Coastguard Worker
25*8975f5c5SAndroid Build Coastguard Worker namespace angle
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker
28*8975f5c5SAndroid Build Coastguard Worker enum class FeatureCategory
29*8975f5c5SAndroid Build Coastguard Worker {
30*8975f5c5SAndroid Build Coastguard Worker FrontendFeatures,
31*8975f5c5SAndroid Build Coastguard Worker FrontendWorkarounds,
32*8975f5c5SAndroid Build Coastguard Worker OpenGLWorkarounds,
33*8975f5c5SAndroid Build Coastguard Worker OpenGLFeatures,
34*8975f5c5SAndroid Build Coastguard Worker D3DWorkarounds,
35*8975f5c5SAndroid Build Coastguard Worker VulkanFeatures,
36*8975f5c5SAndroid Build Coastguard Worker VulkanWorkarounds,
37*8975f5c5SAndroid Build Coastguard Worker VulkanAppWorkarounds,
38*8975f5c5SAndroid Build Coastguard Worker MetalFeatures,
39*8975f5c5SAndroid Build Coastguard Worker MetalWorkarounds,
40*8975f5c5SAndroid Build Coastguard Worker };
41*8975f5c5SAndroid Build Coastguard Worker
42*8975f5c5SAndroid Build Coastguard Worker constexpr char kFeatureCategoryFrontendWorkarounds[] = "Frontend workarounds";
43*8975f5c5SAndroid Build Coastguard Worker constexpr char kFeatureCategoryFrontendFeatures[] = "Frontend features";
44*8975f5c5SAndroid Build Coastguard Worker constexpr char kFeatureCategoryOpenGLWorkarounds[] = "OpenGL workarounds";
45*8975f5c5SAndroid Build Coastguard Worker constexpr char kFeatureCategoryOpenGLFeatures[] = "OpenGL features";
46*8975f5c5SAndroid Build Coastguard Worker constexpr char kFeatureCategoryD3DWorkarounds[] = "D3D workarounds";
47*8975f5c5SAndroid Build Coastguard Worker constexpr char kFeatureCategoryVulkanAppWorkarounds[] = "Vulkan app workarounds";
48*8975f5c5SAndroid Build Coastguard Worker constexpr char kFeatureCategoryVulkanWorkarounds[] = "Vulkan workarounds";
49*8975f5c5SAndroid Build Coastguard Worker constexpr char kFeatureCategoryVulkanFeatures[] = "Vulkan features";
50*8975f5c5SAndroid Build Coastguard Worker constexpr char kFeatureCategoryMetalFeatures[] = "Metal features";
51*8975f5c5SAndroid Build Coastguard Worker constexpr char kFeatureCategoryMetalWorkarounds[] = "Metal workarounds";
52*8975f5c5SAndroid Build Coastguard Worker constexpr char kFeatureCategoryUnknown[] = "Unknown";
53*8975f5c5SAndroid Build Coastguard Worker
FeatureCategoryToString(const FeatureCategory & fc)54*8975f5c5SAndroid Build Coastguard Worker inline const char *FeatureCategoryToString(const FeatureCategory &fc)
55*8975f5c5SAndroid Build Coastguard Worker {
56*8975f5c5SAndroid Build Coastguard Worker switch (fc)
57*8975f5c5SAndroid Build Coastguard Worker {
58*8975f5c5SAndroid Build Coastguard Worker case FeatureCategory::FrontendFeatures:
59*8975f5c5SAndroid Build Coastguard Worker return kFeatureCategoryFrontendFeatures;
60*8975f5c5SAndroid Build Coastguard Worker break;
61*8975f5c5SAndroid Build Coastguard Worker
62*8975f5c5SAndroid Build Coastguard Worker case FeatureCategory::FrontendWorkarounds:
63*8975f5c5SAndroid Build Coastguard Worker return kFeatureCategoryFrontendWorkarounds;
64*8975f5c5SAndroid Build Coastguard Worker break;
65*8975f5c5SAndroid Build Coastguard Worker
66*8975f5c5SAndroid Build Coastguard Worker case FeatureCategory::OpenGLWorkarounds:
67*8975f5c5SAndroid Build Coastguard Worker return kFeatureCategoryOpenGLWorkarounds;
68*8975f5c5SAndroid Build Coastguard Worker break;
69*8975f5c5SAndroid Build Coastguard Worker
70*8975f5c5SAndroid Build Coastguard Worker case FeatureCategory::OpenGLFeatures:
71*8975f5c5SAndroid Build Coastguard Worker return kFeatureCategoryOpenGLFeatures;
72*8975f5c5SAndroid Build Coastguard Worker break;
73*8975f5c5SAndroid Build Coastguard Worker
74*8975f5c5SAndroid Build Coastguard Worker case FeatureCategory::D3DWorkarounds:
75*8975f5c5SAndroid Build Coastguard Worker return kFeatureCategoryD3DWorkarounds;
76*8975f5c5SAndroid Build Coastguard Worker break;
77*8975f5c5SAndroid Build Coastguard Worker
78*8975f5c5SAndroid Build Coastguard Worker case FeatureCategory::VulkanFeatures:
79*8975f5c5SAndroid Build Coastguard Worker return kFeatureCategoryVulkanFeatures;
80*8975f5c5SAndroid Build Coastguard Worker break;
81*8975f5c5SAndroid Build Coastguard Worker
82*8975f5c5SAndroid Build Coastguard Worker case FeatureCategory::VulkanWorkarounds:
83*8975f5c5SAndroid Build Coastguard Worker return kFeatureCategoryVulkanWorkarounds;
84*8975f5c5SAndroid Build Coastguard Worker break;
85*8975f5c5SAndroid Build Coastguard Worker
86*8975f5c5SAndroid Build Coastguard Worker case FeatureCategory::VulkanAppWorkarounds:
87*8975f5c5SAndroid Build Coastguard Worker return kFeatureCategoryVulkanAppWorkarounds;
88*8975f5c5SAndroid Build Coastguard Worker break;
89*8975f5c5SAndroid Build Coastguard Worker
90*8975f5c5SAndroid Build Coastguard Worker case FeatureCategory::MetalFeatures:
91*8975f5c5SAndroid Build Coastguard Worker return kFeatureCategoryMetalFeatures;
92*8975f5c5SAndroid Build Coastguard Worker break;
93*8975f5c5SAndroid Build Coastguard Worker
94*8975f5c5SAndroid Build Coastguard Worker case FeatureCategory::MetalWorkarounds:
95*8975f5c5SAndroid Build Coastguard Worker return kFeatureCategoryMetalWorkarounds;
96*8975f5c5SAndroid Build Coastguard Worker break;
97*8975f5c5SAndroid Build Coastguard Worker
98*8975f5c5SAndroid Build Coastguard Worker default:
99*8975f5c5SAndroid Build Coastguard Worker return kFeatureCategoryUnknown;
100*8975f5c5SAndroid Build Coastguard Worker break;
101*8975f5c5SAndroid Build Coastguard Worker }
102*8975f5c5SAndroid Build Coastguard Worker }
103*8975f5c5SAndroid Build Coastguard Worker
104*8975f5c5SAndroid Build Coastguard Worker constexpr char kFeatureStatusEnabled[] = "enabled";
105*8975f5c5SAndroid Build Coastguard Worker constexpr char kFeatureStatusDisabled[] = "disabled";
106*8975f5c5SAndroid Build Coastguard Worker
FeatureStatusToString(const bool & status)107*8975f5c5SAndroid Build Coastguard Worker inline const char *FeatureStatusToString(const bool &status)
108*8975f5c5SAndroid Build Coastguard Worker {
109*8975f5c5SAndroid Build Coastguard Worker if (status)
110*8975f5c5SAndroid Build Coastguard Worker {
111*8975f5c5SAndroid Build Coastguard Worker return kFeatureStatusEnabled;
112*8975f5c5SAndroid Build Coastguard Worker }
113*8975f5c5SAndroid Build Coastguard Worker return kFeatureStatusDisabled;
114*8975f5c5SAndroid Build Coastguard Worker }
115*8975f5c5SAndroid Build Coastguard Worker
116*8975f5c5SAndroid Build Coastguard Worker struct FeatureInfo;
117*8975f5c5SAndroid Build Coastguard Worker
118*8975f5c5SAndroid Build Coastguard Worker using FeatureMap = std::map<std::string, FeatureInfo *>;
119*8975f5c5SAndroid Build Coastguard Worker using FeatureList = std::vector<const FeatureInfo *>;
120*8975f5c5SAndroid Build Coastguard Worker
121*8975f5c5SAndroid Build Coastguard Worker struct FeatureInfo
122*8975f5c5SAndroid Build Coastguard Worker {
123*8975f5c5SAndroid Build Coastguard Worker FeatureInfo(const FeatureInfo &other);
124*8975f5c5SAndroid Build Coastguard Worker FeatureInfo(const char *name, const FeatureCategory &category, FeatureMap *const mapPtr);
125*8975f5c5SAndroid Build Coastguard Worker ~FeatureInfo();
126*8975f5c5SAndroid Build Coastguard Worker
127*8975f5c5SAndroid Build Coastguard Worker void applyOverride(bool state);
128*8975f5c5SAndroid Build Coastguard Worker
129*8975f5c5SAndroid Build Coastguard Worker // The name of the workaround
130*8975f5c5SAndroid Build Coastguard Worker const char *const name;
131*8975f5c5SAndroid Build Coastguard Worker
132*8975f5c5SAndroid Build Coastguard Worker // The category that the workaround belongs to. Eg. "Vulkan workarounds"
133*8975f5c5SAndroid Build Coastguard Worker const FeatureCategory category;
134*8975f5c5SAndroid Build Coastguard Worker
135*8975f5c5SAndroid Build Coastguard Worker // Whether the workaround is enabled or not. Determined by heuristics like vendor ID and
136*8975f5c5SAndroid Build Coastguard Worker // version, but may be overriden to any value.
137*8975f5c5SAndroid Build Coastguard Worker bool enabled = false;
138*8975f5c5SAndroid Build Coastguard Worker
139*8975f5c5SAndroid Build Coastguard Worker // Whether this feature has an override applied to it, and the condition to
140*8975f5c5SAndroid Build Coastguard Worker // enable it should not be checked.
141*8975f5c5SAndroid Build Coastguard Worker bool hasOverride = false;
142*8975f5c5SAndroid Build Coastguard Worker };
143*8975f5c5SAndroid Build Coastguard Worker
144*8975f5c5SAndroid Build Coastguard Worker inline FeatureInfo::FeatureInfo(const FeatureInfo &other) = default;
FeatureInfo(const char * name,const FeatureCategory & category,FeatureMap * const mapPtr)145*8975f5c5SAndroid Build Coastguard Worker inline FeatureInfo::FeatureInfo(const char *name,
146*8975f5c5SAndroid Build Coastguard Worker const FeatureCategory &category,
147*8975f5c5SAndroid Build Coastguard Worker FeatureMap *const mapPtr)
148*8975f5c5SAndroid Build Coastguard Worker : name(name), category(category), enabled(false)
149*8975f5c5SAndroid Build Coastguard Worker {
150*8975f5c5SAndroid Build Coastguard Worker if (mapPtr != nullptr)
151*8975f5c5SAndroid Build Coastguard Worker {
152*8975f5c5SAndroid Build Coastguard Worker (*mapPtr)[std::string(name)] = this;
153*8975f5c5SAndroid Build Coastguard Worker }
154*8975f5c5SAndroid Build Coastguard Worker }
155*8975f5c5SAndroid Build Coastguard Worker
156*8975f5c5SAndroid Build Coastguard Worker inline FeatureInfo::~FeatureInfo() = default;
157*8975f5c5SAndroid Build Coastguard Worker
158*8975f5c5SAndroid Build Coastguard Worker struct FeatureSetBase
159*8975f5c5SAndroid Build Coastguard Worker {
160*8975f5c5SAndroid Build Coastguard Worker public:
161*8975f5c5SAndroid Build Coastguard Worker FeatureSetBase();
162*8975f5c5SAndroid Build Coastguard Worker ~FeatureSetBase();
163*8975f5c5SAndroid Build Coastguard Worker
164*8975f5c5SAndroid Build Coastguard Worker private:
165*8975f5c5SAndroid Build Coastguard Worker // Non-copyable
166*8975f5c5SAndroid Build Coastguard Worker FeatureSetBase(const FeatureSetBase &other) = delete;
167*8975f5c5SAndroid Build Coastguard Worker FeatureSetBase &operator=(const FeatureSetBase &other) = delete;
168*8975f5c5SAndroid Build Coastguard Worker
169*8975f5c5SAndroid Build Coastguard Worker protected:
170*8975f5c5SAndroid Build Coastguard Worker FeatureMap members = FeatureMap();
171*8975f5c5SAndroid Build Coastguard Worker
172*8975f5c5SAndroid Build Coastguard Worker public:
173*8975f5c5SAndroid Build Coastguard Worker void reset();
174*8975f5c5SAndroid Build Coastguard Worker void overrideFeatures(const std::vector<std::string> &featureNames, bool enabled);
175*8975f5c5SAndroid Build Coastguard Worker void populateFeatureList(FeatureList *features) const;
176*8975f5c5SAndroid Build Coastguard Worker
getFeaturesFeatureSetBase177*8975f5c5SAndroid Build Coastguard Worker const FeatureMap &getFeatures() const { return members; }
178*8975f5c5SAndroid Build Coastguard Worker };
179*8975f5c5SAndroid Build Coastguard Worker
180*8975f5c5SAndroid Build Coastguard Worker inline FeatureSetBase::FeatureSetBase() = default;
181*8975f5c5SAndroid Build Coastguard Worker inline FeatureSetBase::~FeatureSetBase() = default;
182*8975f5c5SAndroid Build Coastguard Worker
183*8975f5c5SAndroid Build Coastguard Worker } // namespace angle
184*8975f5c5SAndroid Build Coastguard Worker
185*8975f5c5SAndroid Build Coastguard Worker #endif // ANGLE_PLATFORM_WORKAROUND_H_
186