diff --git a/BUILD.gn b/BUILD.gn index 78c2c04b89..7d33abb11c 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -183,6 +183,7 @@ source_set("libdawn_native_sources") { "src/dawn_native/Texture.cpp", "src/dawn_native/Texture.h", "src/dawn_native/ToBackend.h", + "src/dawn_native/Toggles.cpp", "src/dawn_native/Toggles.h", "src/dawn_native/dawn_platform.h", ] diff --git a/src/dawn_native/Device.cpp b/src/dawn_native/Device.cpp index d32f02ab79..2306cf0e00 100644 --- a/src/dawn_native/Device.cpp +++ b/src/dawn_native/Device.cpp @@ -506,17 +506,7 @@ namespace dawn_native { } std::vector DeviceBase::GetTogglesUsed() const { - std::vector togglesNameInUse(mTogglesSet.toggleBitset.count()); - - uint32_t index = 0; - for (uint32_t i : IterateBitSet(mTogglesSet.toggleBitset)) { - const char* toggleName = - GetAdapter()->GetInstance()->ToggleEnumToName(static_cast(i)); - togglesNameInUse[index] = toggleName; - ++index; - } - - return togglesNameInUse; + return mTogglesSet.GetEnabledToggleNames(); } bool DeviceBase::IsToggleEnabled(Toggle toggle) const { diff --git a/src/dawn_native/Instance.cpp b/src/dawn_native/Instance.cpp index f686a069be..c106ad17f6 100644 --- a/src/dawn_native/Instance.cpp +++ b/src/dawn_native/Instance.cpp @@ -49,47 +49,6 @@ namespace dawn_native { } #endif // defined(DAWN_ENABLE_BACKEND_VULKAN) - namespace { - - struct ToggleEnumAndInfo { - Toggle toggle; - ToggleInfo info; - }; - - using ToggleEnumAndInfoList = - std::array(Toggle::EnumCount)>; - - static constexpr ToggleEnumAndInfoList kToggleNameAndInfoList = { - {{Toggle::EmulateStoreAndMSAAResolve, - {"emulate_store_and_msaa_resolve", - "Emulate storing into multisampled color attachments and doing MSAA resolve " - "simultaneously. This workaround is enabled by default on the Metal drivers that do " - "not support MTLStoreActionStoreAndMultisampleResolve. To support StoreOp::Store on " - "those platforms, we should do MSAA resolve in another render pass after ending the " - "previous one.", - "https://bugs.chromium.org/p/dawn/issues/detail?id=56"}}, - {Toggle::NonzeroClearResourcesOnCreationForTesting, - {"nonzero_clear_resources_on_creation_for_testing", - "Clears texture to full 1 bits as soon as they are created, but doesn't update " - "the tracking state of the texture. This way we can test the logic of clearing " - "textures that use recycled memory.", - "https://bugs.chromium.org/p/dawn/issues/detail?id=145"}}, - {Toggle::AlwaysResolveIntoZeroLevelAndLayer, - {"always_resolve_into_zero_level_and_layer", - "When the resolve target is a texture view that is created on the non-zero level or " - "layer of a texture, we first resolve into a temporarily 2D texture with only one " - "mipmap level and one array layer, and copy the result of MSAA resolve into the " - "true resolve target. This workaround is enabled by default on the Metal drivers " - "that have bugs when setting non-zero resolveLevel or resolveSlice.", - "https://bugs.chromium.org/p/dawn/issues/detail?id=56"}}, - {Toggle::LazyClearResourceOnFirstUse, - {"lazy_clear_resource_on_first_use", - "Clears resource to zero on first usage. This initializes the resource " - "so that no dirty bits from recycled memory is present in the new resource.", - "https://bugs.chromium.org/p/dawn/issues/detail?id=145"}}}}; - - } // anonymous namespace - // InstanceBase void InstanceBase::DiscoverDefaultAdapters() { @@ -119,51 +78,12 @@ namespace dawn_native { return !ConsumedError(DiscoverAdaptersInternal(options)); } - const char* InstanceBase::ToggleEnumToName(Toggle toggle) { - ASSERT(toggle != Toggle::InvalidEnum); - - const ToggleEnumAndInfo& toggleNameAndInfo = - kToggleNameAndInfoList[static_cast(toggle)]; - ASSERT(toggleNameAndInfo.toggle == toggle); - return toggleNameAndInfo.info.name; - } - const ToggleInfo* InstanceBase::GetToggleInfo(const char* toggleName) { - ASSERT(toggleName); - - EnsureToggleNameToEnumMapInitialized(); - - const auto& iter = mToggleNameToEnumMap.find(toggleName); - if (iter != mToggleNameToEnumMap.cend()) { - return &kToggleNameAndInfoList[static_cast(iter->second)].info; - } - return nullptr; + return mTogglesInfo.GetToggleInfo(toggleName); } Toggle InstanceBase::ToggleNameToEnum(const char* toggleName) { - ASSERT(toggleName); - - EnsureToggleNameToEnumMapInitialized(); - - const auto& iter = mToggleNameToEnumMap.find(toggleName); - if (iter != mToggleNameToEnumMap.cend()) { - return kToggleNameAndInfoList[static_cast(iter->second)].toggle; - } - return Toggle::InvalidEnum; - } - - void InstanceBase::EnsureToggleNameToEnumMapInitialized() { - if (mToggleNameToEnumMapInitialized) { - return; - } - - for (size_t index = 0; index < kToggleNameAndInfoList.size(); ++index) { - const ToggleEnumAndInfo& toggleNameAndInfo = kToggleNameAndInfoList[index]; - ASSERT(index == static_cast(toggleNameAndInfo.toggle)); - mToggleNameToEnumMap[toggleNameAndInfo.info.name] = toggleNameAndInfo.toggle; - } - - mToggleNameToEnumMapInitialized = true; + return mTogglesInfo.ToggleNameToEnum(toggleName); } const std::vector>& InstanceBase::GetAdapters() const { diff --git a/src/dawn_native/Instance.h b/src/dawn_native/Instance.h index 3743dd81f9..a3c5ebbd00 100644 --- a/src/dawn_native/Instance.h +++ b/src/dawn_native/Instance.h @@ -49,7 +49,6 @@ namespace dawn_native { const ToggleInfo* GetToggleInfo(const char* toggleName); Toggle ToggleNameToEnum(const char* toggleName); - const char* ToggleEnumToName(Toggle toggle); void EnableBackendValidation(bool enableBackendValidation); bool IsBackendValidationEnabled() const; @@ -66,19 +65,16 @@ namespace dawn_native { MaybeError DiscoverAdaptersInternal(const AdapterDiscoveryOptionsBase* options); - void EnsureToggleNameToEnumMapInitialized(); - bool mBackendsConnected = false; bool mDiscoveredDefaultAdapters = false; - bool mToggleNameToEnumMapInitialized = false; bool mEnableBackendValidation = false; bool mBeginCaptureOnStartup = false; std::vector> mBackends; std::vector> mAdapters; - std::unordered_map mToggleNameToEnumMap; + TogglesInfo mTogglesInfo; }; } // namespace dawn_native diff --git a/src/dawn_native/Toggles.cpp b/src/dawn_native/Toggles.cpp new file mode 100644 index 0000000000..382f77bc28 --- /dev/null +++ b/src/dawn_native/Toggles.cpp @@ -0,0 +1,135 @@ +// Copyright 2019 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "common/Assert.h" +#include "common/BitSetIterator.h" +#include "dawn_native/Toggles.h" + +namespace dawn_native { + namespace { + + struct ToggleEnumAndInfo { + Toggle toggle; + ToggleInfo info; + }; + + using ToggleEnumAndInfoList = + std::array(Toggle::EnumCount)>; + + static constexpr ToggleEnumAndInfoList kToggleNameAndInfoList = { + {{Toggle::EmulateStoreAndMSAAResolve, + {"emulate_store_and_msaa_resolve", + "Emulate storing into multisampled color attachments and doing MSAA resolve " + "simultaneously. This workaround is enabled by default on the Metal drivers that do " + "not support MTLStoreActionStoreAndMultisampleResolve. To support StoreOp::Store on " + "those platforms, we should do MSAA resolve in another render pass after ending the " + "previous one.", + "https://bugs.chromium.org/p/dawn/issues/detail?id=56"}}, + {Toggle::NonzeroClearResourcesOnCreationForTesting, + {"nonzero_clear_resources_on_creation_for_testing", + "Clears texture to full 1 bits as soon as they are created, but doesn't update " + "the tracking state of the texture. This way we can test the logic of clearing " + "textures that use recycled memory.", + "https://bugs.chromium.org/p/dawn/issues/detail?id=145"}}, + {Toggle::AlwaysResolveIntoZeroLevelAndLayer, + {"always_resolve_into_zero_level_and_layer", + "When the resolve target is a texture view that is created on the non-zero level or " + "layer of a texture, we first resolve into a temporarily 2D texture with only one " + "mipmap level and one array layer, and copy the result of MSAA resolve into the " + "true resolve target. This workaround is enabled by default on the Metal drivers " + "that have bugs when setting non-zero resolveLevel or resolveSlice.", + "https://bugs.chromium.org/p/dawn/issues/detail?id=56"}}, + {Toggle::LazyClearResourceOnFirstUse, + {"lazy_clear_resource_on_first_use", + "Clears resource to zero on first usage. This initializes the resource " + "so that no dirty bits from recycled memory is present in the new resource.", + "https://bugs.chromium.org/p/dawn/issues/detail?id=145"}}}}; + + } // anonymous namespace + + void TogglesSet::SetToggle(Toggle toggle, bool enabled) { + ASSERT(toggle != Toggle::InvalidEnum); + const size_t toggleIndex = static_cast(toggle); + toggleBitset.set(toggleIndex, enabled); + } + + bool TogglesSet::IsEnabled(Toggle toggle) const { + ASSERT(toggle != Toggle::InvalidEnum); + const size_t toggleIndex = static_cast(toggle); + return toggleBitset.test(toggleIndex); + } + + std::vector TogglesSet::GetEnabledToggleNames() const { + std::vector togglesNameInUse(toggleBitset.count()); + + uint32_t index = 0; + for (uint32_t i : IterateBitSet(toggleBitset)) { + const char* toggleName = ToggleEnumToName(static_cast(i)); + togglesNameInUse[index] = toggleName; + ++index; + } + + return togglesNameInUse; + } + + const char* ToggleEnumToName(Toggle toggle) { + ASSERT(toggle != Toggle::InvalidEnum); + + const ToggleEnumAndInfo& toggleNameAndInfo = + kToggleNameAndInfoList[static_cast(toggle)]; + ASSERT(toggleNameAndInfo.toggle == toggle); + return toggleNameAndInfo.info.name; + } + + const ToggleInfo* TogglesInfo::GetToggleInfo(const char* toggleName) { + ASSERT(toggleName); + + EnsureToggleNameToEnumMapInitialized(); + + const auto& iter = mToggleNameToEnumMap.find(toggleName); + if (iter != mToggleNameToEnumMap.cend()) { + return &kToggleNameAndInfoList[static_cast(iter->second)].info; + } + return nullptr; + } + + Toggle TogglesInfo::ToggleNameToEnum(const char* toggleName) { + ASSERT(toggleName); + + EnsureToggleNameToEnumMapInitialized(); + + const auto& iter = mToggleNameToEnumMap.find(toggleName); + if (iter != mToggleNameToEnumMap.cend()) { + return kToggleNameAndInfoList[static_cast(iter->second)].toggle; + } + return Toggle::InvalidEnum; + } + + void TogglesInfo::EnsureToggleNameToEnumMapInitialized() { + if (mToggleNameToEnumMapInitialized) { + return; + } + + for (size_t index = 0; index < kToggleNameAndInfoList.size(); ++index) { + const ToggleEnumAndInfo& toggleNameAndInfo = kToggleNameAndInfoList[index]; + ASSERT(index == static_cast(toggleNameAndInfo.toggle)); + mToggleNameToEnumMap[toggleNameAndInfo.info.name] = toggleNameAndInfo.toggle; + } + + mToggleNameToEnumMapInitialized = true; + } + +} // namespace dawn_native diff --git a/src/dawn_native/Toggles.h b/src/dawn_native/Toggles.h index ac8b3dc1ab..080bf2efe2 100644 --- a/src/dawn_native/Toggles.h +++ b/src/dawn_native/Toggles.h @@ -16,6 +16,8 @@ #define DAWNNATIVE_TOGGLES_H_ #include +#include +#include #include "dawn_native/DawnNative.h" @@ -36,17 +38,25 @@ namespace dawn_native { struct TogglesSet { std::bitset(Toggle::EnumCount)> toggleBitset; - void SetToggle(Toggle toggle, bool enabled) { - ASSERT(toggle != Toggle::InvalidEnum); - const size_t toggleIndex = static_cast(toggle); - toggleBitset.set(toggleIndex, enabled); - } + void SetToggle(Toggle toggle, bool enabled); + bool IsEnabled(Toggle toggle) const; + std::vector GetEnabledToggleNames() const; + }; - bool IsEnabled(Toggle toggle) const { - ASSERT(toggle != Toggle::InvalidEnum); - const size_t toggleIndex = static_cast(toggle); - return toggleBitset.test(toggleIndex); - } + const char* ToggleEnumToName(Toggle toggle); + + class TogglesInfo { + public: + // Used to query the details of a toggle. Return nullptr if toggleName is not a valid name + // of a toggle supported in Dawn. + const ToggleInfo* GetToggleInfo(const char* toggleName); + Toggle ToggleNameToEnum(const char* toggleName); + + private: + void EnsureToggleNameToEnumMapInitialized(); + + bool mToggleNameToEnumMapInitialized = false; + std::unordered_map mToggleNameToEnumMap; }; } // namespace dawn_native