| // |
| // Copyright 2019 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| // Feature.h: Definition of structs to hold feature/workaround information. |
| // |
| |
| #ifndef ANGLE_PLATFORM_FEATURE_H_ |
| #define ANGLE_PLATFORM_FEATURE_H_ |
| |
| #include <map> |
| #include <string> |
| #include <vector> |
| |
| #define ANGLE_FEATURE_CONDITION(set, feature, cond) \ |
| do \ |
| { \ |
| if (!(set)->feature.hasOverride) \ |
| { \ |
| (set)->feature.enabled = cond; \ |
| (set)->feature.condition = ANGLE_STRINGIFY(cond); \ |
| } \ |
| } while (0) |
| |
| namespace angle |
| { |
| |
| enum class FeatureCategory |
| { |
| FrontendFeatures, |
| FrontendWorkarounds, |
| OpenGLWorkarounds, |
| OpenGLFeatures, |
| D3DWorkarounds, |
| VulkanFeatures, |
| VulkanWorkarounds, |
| VulkanAppWorkarounds, |
| MetalFeatures, |
| MetalWorkarounds, |
| }; |
| |
| constexpr char kFeatureCategoryFrontendWorkarounds[] = "Frontend workarounds"; |
| constexpr char kFeatureCategoryFrontendFeatures[] = "Frontend features"; |
| constexpr char kFeatureCategoryOpenGLWorkarounds[] = "OpenGL workarounds"; |
| constexpr char kFeatureCategoryOpenGLFeatures[] = "OpenGL features"; |
| constexpr char kFeatureCategoryD3DWorkarounds[] = "D3D workarounds"; |
| constexpr char kFeatureCategoryVulkanAppWorkarounds[] = "Vulkan app workarounds"; |
| constexpr char kFeatureCategoryVulkanWorkarounds[] = "Vulkan workarounds"; |
| constexpr char kFeatureCategoryVulkanFeatures[] = "Vulkan features"; |
| constexpr char kFeatureCategoryMetalFeatures[] = "Metal features"; |
| constexpr char kFeatureCategoryMetalWorkarounds[] = "Metal workarounds"; |
| constexpr char kFeatureCategoryUnknown[] = "Unknown"; |
| |
| inline const char *FeatureCategoryToString(const FeatureCategory &fc) |
| { |
| switch (fc) |
| { |
| case FeatureCategory::FrontendFeatures: |
| return kFeatureCategoryFrontendFeatures; |
| break; |
| |
| case FeatureCategory::FrontendWorkarounds: |
| return kFeatureCategoryFrontendWorkarounds; |
| break; |
| |
| case FeatureCategory::OpenGLWorkarounds: |
| return kFeatureCategoryOpenGLWorkarounds; |
| break; |
| |
| case FeatureCategory::OpenGLFeatures: |
| return kFeatureCategoryOpenGLFeatures; |
| break; |
| |
| case FeatureCategory::D3DWorkarounds: |
| return kFeatureCategoryD3DWorkarounds; |
| break; |
| |
| case FeatureCategory::VulkanFeatures: |
| return kFeatureCategoryVulkanFeatures; |
| break; |
| |
| case FeatureCategory::VulkanWorkarounds: |
| return kFeatureCategoryVulkanWorkarounds; |
| break; |
| |
| case FeatureCategory::VulkanAppWorkarounds: |
| return kFeatureCategoryVulkanAppWorkarounds; |
| break; |
| |
| case FeatureCategory::MetalFeatures: |
| return kFeatureCategoryMetalFeatures; |
| break; |
| |
| case FeatureCategory::MetalWorkarounds: |
| return kFeatureCategoryMetalWorkarounds; |
| break; |
| |
| default: |
| return kFeatureCategoryUnknown; |
| break; |
| } |
| } |
| |
| constexpr char kFeatureStatusEnabled[] = "enabled"; |
| constexpr char kFeatureStatusDisabled[] = "disabled"; |
| |
| inline const char *FeatureStatusToString(const bool &status) |
| { |
| if (status) |
| { |
| return kFeatureStatusEnabled; |
| } |
| return kFeatureStatusDisabled; |
| } |
| |
| struct FeatureInfo; |
| |
| using FeatureMap = std::map<std::string, FeatureInfo *>; |
| using FeatureList = std::vector<const FeatureInfo *>; |
| |
| struct FeatureInfo |
| { |
| FeatureInfo(const FeatureInfo &other); |
| FeatureInfo(const char *name, |
| const FeatureCategory &category, |
| const char *description, |
| FeatureMap *const mapPtr, |
| const char *bug); |
| ~FeatureInfo(); |
| |
| void applyOverride(bool state); |
| |
| // The name of the workaround, lowercase, camel_case |
| const char *const name; |
| |
| // The category that the workaround belongs to. Eg. "Vulkan workarounds" |
| const FeatureCategory category; |
| |
| // A short description to be read by the user. |
| const char *const description; |
| |
| // A link to the bug, if any |
| const char *const bug; |
| |
| // Whether the workaround is enabled or not. Determined by heuristics like vendor ID and |
| // version, but may be overriden to any value. |
| bool enabled = false; |
| |
| // Whether this feature has an override applied to it, and the condition to |
| // enable it should not be checked. |
| bool hasOverride = false; |
| |
| // A stringified version of the condition used to set 'enabled'. ie "IsNvidia() && IsApple()" |
| const char *condition; |
| }; |
| |
| inline FeatureInfo::FeatureInfo(const FeatureInfo &other) = default; |
| inline FeatureInfo::FeatureInfo(const char *name, |
| const FeatureCategory &category, |
| const char *description, |
| FeatureMap *const mapPtr, |
| const char *bug = "") |
| : name(name), |
| category(category), |
| description(description), |
| bug(bug), |
| enabled(false), |
| condition("") |
| { |
| if (mapPtr != nullptr) |
| { |
| (*mapPtr)[std::string(name)] = this; |
| } |
| } |
| |
| inline FeatureInfo::~FeatureInfo() = default; |
| |
| struct FeatureSetBase |
| { |
| public: |
| FeatureSetBase(); |
| ~FeatureSetBase(); |
| |
| private: |
| // Non-copyable |
| FeatureSetBase(const FeatureSetBase &other) = delete; |
| FeatureSetBase &operator=(const FeatureSetBase &other) = delete; |
| |
| protected: |
| FeatureMap members = FeatureMap(); |
| |
| public: |
| void reset(); |
| void overrideFeatures(const std::vector<std::string> &featureNames, bool enabled); |
| void populateFeatureList(FeatureList *features) const; |
| |
| const FeatureMap &getFeatures() const { return members; } |
| }; |
| |
| inline FeatureSetBase::FeatureSetBase() = default; |
| inline FeatureSetBase::~FeatureSetBase() = default; |
| |
| } // namespace angle |
| |
| #endif // ANGLE_PLATFORM_WORKAROUND_H_ |