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/Extensions.h"
20 
21 namespace dawn_native {
22     namespace {
23 
24         struct ExtensionEnumAndInfo {
25             Extension extension;
26             ExtensionInfo info;
27             bool WGPUDeviceProperties::*memberInWGPUDeviceProperties;
28         };
29 
30         using ExtensionEnumAndInfoList =
31             std::array<ExtensionEnumAndInfo, static_cast<size_t>(Extension::EnumCount)>;
32 
33         static constexpr ExtensionEnumAndInfoList kExtensionNameAndInfoList = {
34             {{Extension::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 
39     }  // anonymous namespace
40 
EnableExtension(Extension extension)41     void ExtensionsSet::EnableExtension(Extension extension) {
42         ASSERT(extension != Extension::InvalidEnum);
43         const size_t extensionIndex = static_cast<size_t>(extension);
44         extensionsBitSet.set(extensionIndex);
45     }
46 
IsEnabled(Extension extension) const47     bool ExtensionsSet::IsEnabled(Extension extension) const {
48         ASSERT(extension != Extension::InvalidEnum);
49         const size_t extensionIndex = static_cast<size_t>(extension);
50         return extensionsBitSet[extensionIndex];
51     }
52 
GetEnabledExtensionNames() const53     std::vector<const char*> ExtensionsSet::GetEnabledExtensionNames() const {
54         std::vector<const char*> enabledExtensionNames(extensionsBitSet.count());
55 
56         uint32_t index = 0;
57         for (uint32_t i : IterateBitSet(extensionsBitSet)) {
58             const char* extensionName = ExtensionEnumToName(static_cast<Extension>(i));
59             enabledExtensionNames[index] = extensionName;
60             ++index;
61         }
62         return enabledExtensionNames;
63     }
64 
InitializeDeviceProperties(WGPUDeviceProperties * properties) const65     void ExtensionsSet::InitializeDeviceProperties(WGPUDeviceProperties* properties) const {
66         ASSERT(properties != nullptr);
67 
68         for (uint32_t i : IterateBitSet(extensionsBitSet)) {
69             properties->*(kExtensionNameAndInfoList[i].memberInWGPUDeviceProperties) = true;
70         }
71     }
72 
ExtensionEnumToName(Extension extension)73     const char* ExtensionEnumToName(Extension extension) {
74         ASSERT(extension != Extension::InvalidEnum);
75 
76         const ExtensionEnumAndInfo& extensionNameAndInfo =
77             kExtensionNameAndInfoList[static_cast<size_t>(extension)];
78         ASSERT(extensionNameAndInfo.extension == extension);
79         return extensionNameAndInfo.info.name;
80     }
81 
ExtensionsInfo()82     ExtensionsInfo::ExtensionsInfo() {
83         for (size_t index = 0; index < kExtensionNameAndInfoList.size(); ++index) {
84             const ExtensionEnumAndInfo& extensionNameAndInfo = kExtensionNameAndInfoList[index];
85             ASSERT(index == static_cast<size_t>(extensionNameAndInfo.extension));
86             mExtensionNameToEnumMap[extensionNameAndInfo.info.name] =
87                 extensionNameAndInfo.extension;
88         }
89     }
90 
GetExtensionInfo(const char * extensionName) const91     const ExtensionInfo* ExtensionsInfo::GetExtensionInfo(const char* extensionName) const {
92         ASSERT(extensionName);
93 
94         const auto& iter = mExtensionNameToEnumMap.find(extensionName);
95         if (iter != mExtensionNameToEnumMap.cend()) {
96             return &kExtensionNameAndInfoList[static_cast<size_t>(iter->second)].info;
97         }
98         return nullptr;
99     }
100 
ExtensionNameToEnum(const char * extensionName) const101     Extension ExtensionsInfo::ExtensionNameToEnum(const char* extensionName) const {
102         ASSERT(extensionName);
103 
104         const auto& iter = mExtensionNameToEnumMap.find(extensionName);
105         if (iter != mExtensionNameToEnumMap.cend()) {
106             return kExtensionNameAndInfoList[static_cast<size_t>(iter->second)].extension;
107         }
108         return Extension::InvalidEnum;
109     }
110 
ExtensionNamesToExtensionsSet(const std::vector<const char * > & requiredExtensions) const111     ExtensionsSet ExtensionsInfo::ExtensionNamesToExtensionsSet(
112         const std::vector<const char*>& requiredExtensions) const {
113         ExtensionsSet extensionsSet;
114 
115         for (const char* extensionName : requiredExtensions) {
116             Extension extensionEnum = ExtensionNameToEnum(extensionName);
117             ASSERT(extensionEnum != Extension::InvalidEnum);
118             extensionsSet.EnableExtension(extensionEnum);
119         }
120         return extensionsSet;
121     }
122 
123 }  // namespace dawn_native
124