1 // Copyright 2019 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include <array> 16 17 #include "common/Assert.h" 18 #include "common/BitSetIterator.h" 19 #include "dawn_native/Features.h" 20 21 namespace dawn_native { 22 namespace { 23 24 struct FeatureEnumAndInfo { 25 Feature feature; 26 FeatureInfo info; 27 bool WGPUDeviceProperties::*memberInWGPUDeviceProperties; 28 }; 29 30 using FeatureEnumAndInfoList = 31 std::array<FeatureEnumAndInfo, static_cast<size_t>(Feature::EnumCount)>; 32 33 static constexpr FeatureEnumAndInfoList kFeatureNameAndInfoList = { 34 {{Feature::TextureCompressionBC, 35 {"texture-compression-bc", "Support Block Compressed (BC) texture formats", 36 "https://bugs.chromium.org/p/dawn/issues/detail?id=42"}, 37 &WGPUDeviceProperties::textureCompressionBC}, 38 {Feature::TextureCompressionETC2, 39 {"texture-compression-etc2", 40 "Support Ericsson Texture Compressed (ETC2/EAC) texture " 41 "formats", 42 "https://bugs.chromium.org/p/dawn/issues/detail?id=955"}, 43 &WGPUDeviceProperties::textureCompressionETC2}, 44 {Feature::TextureCompressionASTC, 45 {"texture-compression-astc", 46 "Support Adaptable Scalable Texture Compressed (ASTC) " 47 "texture formats", 48 "https://bugs.chromium.org/p/dawn/issues/detail?id=955"}, 49 &WGPUDeviceProperties::textureCompressionASTC}, 50 {Feature::ShaderFloat16, 51 {"shader-float16", 52 "Support 16bit float arithmetic and declarations in uniform and storage buffers", 53 "https://bugs.chromium.org/p/dawn/issues/detail?id=426"}, 54 &WGPUDeviceProperties::shaderFloat16}, 55 {Feature::PipelineStatisticsQuery, 56 {"pipeline-statistics-query", "Support Pipeline Statistics Query", 57 "https://bugs.chromium.org/p/dawn/issues/detail?id=434"}, 58 &WGPUDeviceProperties::pipelineStatisticsQuery}, 59 {Feature::TimestampQuery, 60 {"timestamp-query", "Support Timestamp Query", 61 "https://bugs.chromium.org/p/dawn/issues/detail?id=434"}, 62 &WGPUDeviceProperties::timestampQuery}, 63 {Feature::DepthClamping, 64 {"depth-clamping", "Clamp depth to [0, 1] in NDC space instead of clipping", 65 "https://bugs.chromium.org/p/dawn/issues/detail?id=716"}, 66 &WGPUDeviceProperties::depthClamping}, 67 {Feature::Depth24UnormStencil8, 68 {"depth24unorm-stencil8", "Support depth24unorm-stencil8 texture format", 69 "https://bugs.chromium.org/p/dawn/issues/detail?id=690"}, 70 &WGPUDeviceProperties::depth24UnormStencil8}, 71 {Feature::Depth32FloatStencil8, 72 {"depth32float-stencil8", "Support depth32float-stencil8 texture format", 73 "https://bugs.chromium.org/p/dawn/issues/detail?id=690"}, 74 &WGPUDeviceProperties::depth32FloatStencil8}, 75 {Feature::DawnInternalUsages, 76 {"dawn-internal-usages", 77 "Add internal usages to resources to affect how the texture is allocated, but not " 78 "frontend validation. Other internal commands may access this usage.", 79 "https://dawn.googlesource.com/dawn/+/refs/heads/main/docs/features/" 80 "dawn_internal_usages.md"}, 81 &WGPUDeviceProperties::dawnInternalUsages}, 82 {Feature::MultiPlanarFormats, 83 {"multiplanar-formats", 84 "Import and use multi-planar texture formats with per plane views", 85 "https://bugs.chromium.org/p/dawn/issues/detail?id=551"}, 86 &WGPUDeviceProperties::multiPlanarFormats}}}; 87 88 } // anonymous namespace 89 EnableFeature(Feature feature)90 void FeaturesSet::EnableFeature(Feature feature) { 91 ASSERT(feature != Feature::InvalidEnum); 92 const size_t featureIndex = static_cast<size_t>(feature); 93 featuresBitSet.set(featureIndex); 94 } 95 IsEnabled(Feature feature) const96 bool FeaturesSet::IsEnabled(Feature feature) const { 97 ASSERT(feature != Feature::InvalidEnum); 98 const size_t featureIndex = static_cast<size_t>(feature); 99 return featuresBitSet[featureIndex]; 100 } 101 GetEnabledFeatureNames() const102 std::vector<const char*> FeaturesSet::GetEnabledFeatureNames() const { 103 std::vector<const char*> enabledFeatureNames(featuresBitSet.count()); 104 105 uint32_t index = 0; 106 for (uint32_t i : IterateBitSet(featuresBitSet)) { 107 const char* featureName = FeatureEnumToName(static_cast<Feature>(i)); 108 enabledFeatureNames[index] = featureName; 109 ++index; 110 } 111 return enabledFeatureNames; 112 } 113 InitializeDeviceProperties(WGPUDeviceProperties * properties) const114 void FeaturesSet::InitializeDeviceProperties(WGPUDeviceProperties* properties) const { 115 ASSERT(properties != nullptr); 116 117 for (uint32_t i : IterateBitSet(featuresBitSet)) { 118 properties->*(kFeatureNameAndInfoList[i].memberInWGPUDeviceProperties) = true; 119 } 120 } 121 FeatureEnumToName(Feature feature)122 const char* FeatureEnumToName(Feature feature) { 123 ASSERT(feature != Feature::InvalidEnum); 124 125 const FeatureEnumAndInfo& featureNameAndInfo = 126 kFeatureNameAndInfoList[static_cast<size_t>(feature)]; 127 ASSERT(featureNameAndInfo.feature == feature); 128 return featureNameAndInfo.info.name; 129 } 130 FeaturesInfo()131 FeaturesInfo::FeaturesInfo() { 132 for (size_t index = 0; index < kFeatureNameAndInfoList.size(); ++index) { 133 const FeatureEnumAndInfo& featureNameAndInfo = kFeatureNameAndInfoList[index]; 134 ASSERT(index == static_cast<size_t>(featureNameAndInfo.feature)); 135 mFeatureNameToEnumMap[featureNameAndInfo.info.name] = featureNameAndInfo.feature; 136 } 137 } 138 GetFeatureInfo(const char * featureName) const139 const FeatureInfo* FeaturesInfo::GetFeatureInfo(const char* featureName) const { 140 ASSERT(featureName); 141 142 const auto& iter = mFeatureNameToEnumMap.find(featureName); 143 if (iter != mFeatureNameToEnumMap.cend()) { 144 return &kFeatureNameAndInfoList[static_cast<size_t>(iter->second)].info; 145 } 146 return nullptr; 147 } 148 FeatureNameToEnum(const char * featureName) const149 Feature FeaturesInfo::FeatureNameToEnum(const char* featureName) const { 150 ASSERT(featureName); 151 152 const auto& iter = mFeatureNameToEnumMap.find(featureName); 153 if (iter != mFeatureNameToEnumMap.cend()) { 154 return kFeatureNameAndInfoList[static_cast<size_t>(iter->second)].feature; 155 } 156 157 // TODO(dawn:550): Remove this fallback logic when Chromium is updated. 158 constexpr std::array<std::pair<const char*, const char*>, 6> 159 kReplacementsForDeprecatedNames = {{ 160 {"texture_compression_bc", "texture-compression-bc"}, 161 {"depth_clamping", "depth-clamping"}, 162 {"pipeline_statistics_query", "pipeline-statistics-query"}, 163 {"shader_float16", "shader-float16"}, 164 {"timestamp_query", "timestamp-query"}, 165 {"multiplanar_formats", "multiplanar-formats"}, 166 }}; 167 for (const auto& replacement : kReplacementsForDeprecatedNames) { 168 if (strcmp(featureName, replacement.first) == 0) { 169 return FeatureNameToEnum(replacement.second); 170 } 171 } 172 173 return Feature::InvalidEnum; 174 } 175 FeatureNamesToFeaturesSet(const std::vector<const char * > & requiredFeatures) const176 FeaturesSet FeaturesInfo::FeatureNamesToFeaturesSet( 177 const std::vector<const char*>& requiredFeatures) const { 178 FeaturesSet featuresSet; 179 180 for (const char* featureName : requiredFeatures) { 181 Feature featureEnum = FeatureNameToEnum(featureName); 182 ASSERT(featureEnum != Feature::InvalidEnum); 183 featuresSet.EnableFeature(featureEnum); 184 } 185 return featuresSet; 186 } 187 188 } // namespace dawn_native 189