blob: 034eabf128c6b0dbc4ea03942431d84754d99af8 [file] [log] [blame]
// 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
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
#include <array>
#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<ToggleEnumAndInfo, static_cast<size_t>(Toggle::EnumCount)>;
static constexpr ToggleEnumAndInfoList kToggleNameAndInfoList = {{
"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.",
"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.",
"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.",
"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.",
"Turn off vsync when rendering. In order to do performance test or run perf tests, "
"turn off vsync so that the fps can exeed 60.",
"Split texture-to-texture copy into two copies: copy from source texture into a "
"temporary buffer, and copy from the temporary buffer into the destination texture "
"when copying between compressed textures that don't have block-aligned sizes. This "
"workaround is enabled by default on all Vulkan drivers to solve an issue in the "
"Vulkan SPEC about the texture-to-texture copies with compressed formats. See #1005 "
"( for more details.",
"Enable support for resource heap tier 2. Resource heap tier 2 allows mixing of "
"texture and buffers in the same heap. This allows better heap re-use and reduces "
"Use the D3D12 render pass API introduced in Windows build 1809 by default. On "
"versions of Windows prior to build 1809, or when this toggle is turned off, Dawn "
"will emulate a render pass.",
"Enable residency management. This allows page-in and page-out of resource heaps in "
"GPU memory. This component improves overcommitted performance by keeping the most "
"recently used resources local to the GPU. Turning this component off can cause "
"allocation failures when application memory exceeds physical device memory.",
{"skip_validation", "Skip expensive validation of Dawn commands.",
"Vulkan mandates support of either D32_FLOAT_S8 or D24_UNORM_S8. When available the "
"backend will use D32S8 (toggle to on) but setting the toggle to off will make it"
"use the D24S8 format when possible.",
"Disables the use of sampler compare on Metal. This is unsupported before A9 "
"The query set on Metal need to create MTLCounterSampleBuffer which storage mode "
"must be either MTLStorageModeShared or MTLStorageModePrivate. But the private mode "
"does not work properly on Intel platforms. The workaround is use shared mode "
"Disables the use of non-zero base vertex which is unsupported on some platforms.",
"Disables the use of non-zero base instance which is unsupported on some "
"Disables the use of indexed draw buffer state which is unsupported on some "
"Enable use of a small D3D12 shader visible heap, instead of using a large one by "
"default. This setting is used to test bindgroup encoding.",
"Use DXC instead of FXC for compiling HLSL when both dxcompiler.dll and dxil.dll "
"is available.",
{"disable_robustness", "Disable robust buffer access", ""}},
"Uses vertex pulling to protect out-of-bounds reads on Metal",
"Produces validation errors on API entry points or parameter combinations that "
"aren't considered secure yet.",
{"use_tint_generator", "Use Tint instead of SPRIV-cross to generate shaders.",
{"use_tint_inspector", "Use Tint instead of SPRIV-cross for shader reflection.",
"Call glFlush before glClientWaitSync to work around bugs in the latter",
// Dummy comment to separate the }} so it is clearer what to copy-paste to add a toggle.
} // anonymous namespace
void TogglesSet::Set(Toggle toggle, bool enabled) {
ASSERT(toggle != Toggle::InvalidEnum);
const size_t toggleIndex = static_cast<size_t>(toggle);
toggleBitset.set(toggleIndex, enabled);
bool TogglesSet::Has(Toggle toggle) const {
ASSERT(toggle != Toggle::InvalidEnum);
const size_t toggleIndex = static_cast<size_t>(toggle);
return toggleBitset.test(toggleIndex);
std::vector<const char*> TogglesSet::GetContainedToggleNames() const {
std::vector<const char*> togglesNameInUse(toggleBitset.count());
uint32_t index = 0;
for (uint32_t i : IterateBitSet(toggleBitset)) {
const char* toggleName = ToggleEnumToName(static_cast<Toggle>(i));
togglesNameInUse[index] = toggleName;
return togglesNameInUse;
const char* ToggleEnumToName(Toggle toggle) {
ASSERT(toggle != Toggle::InvalidEnum);
const ToggleEnumAndInfo& toggleNameAndInfo =
ASSERT(toggleNameAndInfo.toggle == toggle);
const ToggleInfo* TogglesInfo::GetToggleInfo(const char* toggleName) {
const auto& iter = mToggleNameToEnumMap.find(toggleName);
if (iter != mToggleNameToEnumMap.cend()) {
return &kToggleNameAndInfoList[static_cast<size_t>(iter->second)].info;
return nullptr;
Toggle TogglesInfo::ToggleNameToEnum(const char* toggleName) {
const auto& iter = mToggleNameToEnumMap.find(toggleName);
if (iter != mToggleNameToEnumMap.cend()) {
return kToggleNameAndInfoList[static_cast<size_t>(iter->second)].toggle;
return Toggle::InvalidEnum;
void TogglesInfo::EnsureToggleNameToEnumMapInitialized() {
if (mToggleNameToEnumMapInitialized) {
for (size_t index = 0; index < kToggleNameAndInfoList.size(); ++index) {
const ToggleEnumAndInfo& toggleNameAndInfo = kToggleNameAndInfoList[index];
ASSERT(index == static_cast<size_t>(toggleNameAndInfo.toggle));
mToggleNameToEnumMap[] = toggleNameAndInfo.toggle;
mToggleNameToEnumMapInitialized = true;
} // namespace dawn_native