blob: 913706ceaf650e2b98101a1bf298305d01699d2e [file] [log] [blame]
François Beaufort3f689a42021-10-04 11:30:02 +00001// 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
21namespace 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,
Corentin Wallez2d176202021-10-11 10:18:09 +000035 {"texture-compression-bc", "Support Block Compressed (BC) texture formats",
François Beaufort3f689a42021-10-04 11:30:02 +000036 "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,
Corentin Wallez2d176202021-10-11 10:18:09 +000051 {"shader-float16",
François Beaufort3f689a42021-10-04 11:30:02 +000052 "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,
Corentin Wallez2d176202021-10-11 10:18:09 +000056 {"pipeline-statistics-query", "Support Pipeline Statistics Query",
François Beaufort3f689a42021-10-04 11:30:02 +000057 "https://bugs.chromium.org/p/dawn/issues/detail?id=434"},
58 &WGPUDeviceProperties::pipelineStatisticsQuery},
59 {Feature::TimestampQuery,
Corentin Wallez2d176202021-10-11 10:18:09 +000060 {"timestamp-query", "Support Timestamp Query",
François Beaufort3f689a42021-10-04 11:30:02 +000061 "https://bugs.chromium.org/p/dawn/issues/detail?id=434"},
62 &WGPUDeviceProperties::timestampQuery},
63 {Feature::DepthClamping,
Corentin Wallez2d176202021-10-11 10:18:09 +000064 {"depth-clamping", "Clamp depth to [0, 1] in NDC space instead of clipping",
François Beaufort3f689a42021-10-04 11:30:02 +000065 "https://bugs.chromium.org/p/dawn/issues/detail?id=716"},
66 &WGPUDeviceProperties::depthClamping},
Li Haoa3299972021-11-25 01:11:57 +000067 {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},
François Beaufort3f689a42021-10-04 11:30:02 +000075 {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,
Corentin Wallez2d176202021-10-11 10:18:09 +000083 {"multiplanar-formats",
François Beaufort3f689a42021-10-04 11:30:02 +000084 "Import and use multi-planar texture formats with per plane views",
85 "https://bugs.chromium.org/p/dawn/issues/detail?id=551"},
Austin Eng2f218e22021-12-22 19:02:23 +000086 &WGPUDeviceProperties::multiPlanarFormats},
87 {Feature::DawnNative,
88 {"dawn-native", "WebGPU is running on top of dawn_native.",
89 "https://dawn.googlesource.com/dawn/+/refs/heads/main/docs/features/"
90 "dawn_native.md"},
91 &WGPUDeviceProperties::dawnNative}}};
François Beaufort3f689a42021-10-04 11:30:02 +000092
Austin Eng5397f9f2021-12-14 23:22:46 +000093 Feature FromAPIFeature(wgpu::FeatureName feature) {
94 switch (feature) {
95 case wgpu::FeatureName::Undefined:
96 return Feature::InvalidEnum;
97
98 case wgpu::FeatureName::TimestampQuery:
99 return Feature::TimestampQuery;
100 case wgpu::FeatureName::PipelineStatisticsQuery:
101 return Feature::PipelineStatisticsQuery;
102 case wgpu::FeatureName::TextureCompressionBC:
103 return Feature::TextureCompressionBC;
104 case wgpu::FeatureName::TextureCompressionETC2:
105 return Feature::TextureCompressionETC2;
106 case wgpu::FeatureName::TextureCompressionASTC:
107 return Feature::TextureCompressionASTC;
108 case wgpu::FeatureName::DepthClamping:
109 return Feature::DepthClamping;
110 case wgpu::FeatureName::Depth24UnormStencil8:
111 return Feature::Depth24UnormStencil8;
112 case wgpu::FeatureName::Depth32FloatStencil8:
113 return Feature::Depth32FloatStencil8;
Austin Eng89ddadc2021-12-15 00:12:30 +0000114 case wgpu::FeatureName::DawnShaderFloat16:
115 return Feature::ShaderFloat16;
116 case wgpu::FeatureName::DawnInternalUsages:
117 return Feature::DawnInternalUsages;
118 case wgpu::FeatureName::DawnMultiPlanarFormats:
119 return Feature::MultiPlanarFormats;
Austin Eng2f218e22021-12-22 19:02:23 +0000120 case wgpu::FeatureName::DawnNative:
121 return Feature::DawnNative;
Austin Eng5397f9f2021-12-14 23:22:46 +0000122
123 case wgpu::FeatureName::IndirectFirstInstance:
124 return Feature::InvalidEnum;
125 }
126 return Feature::InvalidEnum;
127 }
128
Austin Eng89ddadc2021-12-15 00:12:30 +0000129 wgpu::FeatureName ToAPIFeature(Feature feature) {
130 switch (feature) {
131 case Feature::TextureCompressionBC:
132 return wgpu::FeatureName::TextureCompressionBC;
133 case Feature::TextureCompressionETC2:
134 return wgpu::FeatureName::TextureCompressionETC2;
135 case Feature::TextureCompressionASTC:
136 return wgpu::FeatureName::TextureCompressionASTC;
137 case Feature::PipelineStatisticsQuery:
138 return wgpu::FeatureName::PipelineStatisticsQuery;
139 case Feature::TimestampQuery:
140 return wgpu::FeatureName::TimestampQuery;
141 case Feature::DepthClamping:
142 return wgpu::FeatureName::DepthClamping;
143 case Feature::Depth24UnormStencil8:
144 return wgpu::FeatureName::Depth24UnormStencil8;
145 case Feature::Depth32FloatStencil8:
146 return wgpu::FeatureName::Depth32FloatStencil8;
147 case Feature::ShaderFloat16:
148 return wgpu::FeatureName::DawnShaderFloat16;
149 case Feature::DawnInternalUsages:
150 return wgpu::FeatureName::DawnInternalUsages;
151 case Feature::MultiPlanarFormats:
152 return wgpu::FeatureName::DawnMultiPlanarFormats;
Austin Eng2f218e22021-12-22 19:02:23 +0000153 case Feature::DawnNative:
154 return wgpu::FeatureName::DawnNative;
Austin Eng89ddadc2021-12-15 00:12:30 +0000155
156 case Feature::EnumCount:
157 UNREACHABLE();
158 }
159 }
160
François Beaufort3f689a42021-10-04 11:30:02 +0000161 } // anonymous namespace
162
163 void FeaturesSet::EnableFeature(Feature feature) {
164 ASSERT(feature != Feature::InvalidEnum);
165 const size_t featureIndex = static_cast<size_t>(feature);
166 featuresBitSet.set(featureIndex);
167 }
168
Austin Eng2f218e22021-12-22 19:02:23 +0000169 void FeaturesSet::EnableFeature(wgpu::FeatureName feature) {
170 EnableFeature(FromAPIFeature(feature));
171 }
172
François Beaufort3f689a42021-10-04 11:30:02 +0000173 bool FeaturesSet::IsEnabled(Feature feature) const {
174 ASSERT(feature != Feature::InvalidEnum);
175 const size_t featureIndex = static_cast<size_t>(feature);
176 return featuresBitSet[featureIndex];
177 }
178
Austin Eng5397f9f2021-12-14 23:22:46 +0000179 bool FeaturesSet::IsEnabled(wgpu::FeatureName feature) const {
180 Feature f = FromAPIFeature(feature);
181 return f != Feature::InvalidEnum && IsEnabled(f);
182 }
183
Austin Eng89ddadc2021-12-15 00:12:30 +0000184 uint32_t FeaturesSet::EnumerateFeatures(wgpu::FeatureName* features) const {
185 for (uint32_t i : IterateBitSet(featuresBitSet)) {
186 wgpu::FeatureName feature = ToAPIFeature(static_cast<Feature>(i));
187 if (features != nullptr) {
188 *features = feature;
189 features += 1;
190 }
191 }
192 return featuresBitSet.count();
193 }
194
François Beaufort3f689a42021-10-04 11:30:02 +0000195 std::vector<const char*> FeaturesSet::GetEnabledFeatureNames() const {
196 std::vector<const char*> enabledFeatureNames(featuresBitSet.count());
197
198 uint32_t index = 0;
199 for (uint32_t i : IterateBitSet(featuresBitSet)) {
Austin Eng2f218e22021-12-22 19:02:23 +0000200 Feature feature = static_cast<Feature>(i);
201 ASSERT(feature != Feature::InvalidEnum);
202
203 const FeatureEnumAndInfo& featureNameAndInfo = kFeatureNameAndInfoList[i];
204 ASSERT(featureNameAndInfo.feature == feature);
205
206 enabledFeatureNames[index] = featureNameAndInfo.info.name;
François Beaufort3f689a42021-10-04 11:30:02 +0000207 ++index;
208 }
209 return enabledFeatureNames;
210 }
211
212 void FeaturesSet::InitializeDeviceProperties(WGPUDeviceProperties* properties) const {
213 ASSERT(properties != nullptr);
214
215 for (uint32_t i : IterateBitSet(featuresBitSet)) {
216 properties->*(kFeatureNameAndInfoList[i].memberInWGPUDeviceProperties) = true;
217 }
218 }
219
Austin Eng2f218e22021-12-22 19:02:23 +0000220 wgpu::FeatureName FeatureEnumToAPIFeature(Feature feature) {
François Beaufort3f689a42021-10-04 11:30:02 +0000221 ASSERT(feature != Feature::InvalidEnum);
Austin Eng2f218e22021-12-22 19:02:23 +0000222 return ToAPIFeature(feature);
François Beaufort3f689a42021-10-04 11:30:02 +0000223 }
224
225 FeaturesInfo::FeaturesInfo() {
226 for (size_t index = 0; index < kFeatureNameAndInfoList.size(); ++index) {
227 const FeatureEnumAndInfo& featureNameAndInfo = kFeatureNameAndInfoList[index];
228 ASSERT(index == static_cast<size_t>(featureNameAndInfo.feature));
229 mFeatureNameToEnumMap[featureNameAndInfo.info.name] = featureNameAndInfo.feature;
230 }
231 }
232
Austin Eng2f218e22021-12-22 19:02:23 +0000233 const FeatureInfo* FeaturesInfo::GetFeatureInfo(wgpu::FeatureName feature) const {
234 Feature f = FromAPIFeature(feature);
235 if (f == Feature::InvalidEnum) {
236 return nullptr;
François Beaufort3f689a42021-10-04 11:30:02 +0000237 }
Austin Eng2f218e22021-12-22 19:02:23 +0000238 return &kFeatureNameAndInfoList[static_cast<size_t>(f)].info;
François Beaufort3f689a42021-10-04 11:30:02 +0000239 }
240
241 Feature FeaturesInfo::FeatureNameToEnum(const char* featureName) const {
242 ASSERT(featureName);
243
244 const auto& iter = mFeatureNameToEnumMap.find(featureName);
245 if (iter != mFeatureNameToEnumMap.cend()) {
246 return kFeatureNameAndInfoList[static_cast<size_t>(iter->second)].feature;
247 }
Corentin Wallez2d176202021-10-11 10:18:09 +0000248
249 // TODO(dawn:550): Remove this fallback logic when Chromium is updated.
250 constexpr std::array<std::pair<const char*, const char*>, 6>
251 kReplacementsForDeprecatedNames = {{
252 {"texture_compression_bc", "texture-compression-bc"},
253 {"depth_clamping", "depth-clamping"},
254 {"pipeline_statistics_query", "pipeline-statistics-query"},
255 {"shader_float16", "shader-float16"},
256 {"timestamp_query", "timestamp-query"},
257 {"multiplanar_formats", "multiplanar-formats"},
258 }};
259 for (const auto& replacement : kReplacementsForDeprecatedNames) {
260 if (strcmp(featureName, replacement.first) == 0) {
261 return FeatureNameToEnum(replacement.second);
262 }
263 }
264
François Beaufort3f689a42021-10-04 11:30:02 +0000265 return Feature::InvalidEnum;
266 }
267
Austin Eng2f218e22021-12-22 19:02:23 +0000268 wgpu::FeatureName FeaturesInfo::FeatureNameToAPIEnum(const char* featureName) const {
269 Feature f = FeatureNameToEnum(featureName);
270 if (f != Feature::InvalidEnum) {
271 return ToAPIFeature(f);
François Beaufort3f689a42021-10-04 11:30:02 +0000272 }
Austin Eng2f218e22021-12-22 19:02:23 +0000273 // Pass something invalid.
274 return static_cast<wgpu::FeatureName>(-1);
François Beaufort3f689a42021-10-04 11:30:02 +0000275 }
276
277} // namespace dawn_native