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/Toggles.h" 20 21 namespace dawn_native { 22 namespace { 23 24 struct ToggleEnumAndInfo { 25 Toggle toggle; 26 ToggleInfo info; 27 }; 28 29 using ToggleEnumAndInfoList = 30 std::array<ToggleEnumAndInfo, static_cast<size_t>(Toggle::EnumCount)>; 31 32 static constexpr ToggleEnumAndInfoList kToggleNameAndInfoList = {{ 33 {Toggle::EmulateStoreAndMSAAResolve, 34 {"emulate_store_and_msaa_resolve", 35 "Emulate storing into multisampled color attachments and doing MSAA resolve " 36 "simultaneously. This workaround is enabled by default on the Metal drivers that do " 37 "not support MTLStoreActionStoreAndMultisampleResolve. To support StoreOp::Store on " 38 "those platforms, we should do MSAA resolve in another render pass after ending the " 39 "previous one.", 40 "https://crbug.com/dawn/56"}}, 41 {Toggle::NonzeroClearResourcesOnCreationForTesting, 42 {"nonzero_clear_resources_on_creation_for_testing", 43 "Clears texture to full 1 bits as soon as they are created, but doesn't update " 44 "the tracking state of the texture. This way we can test the logic of clearing " 45 "textures that use recycled memory.", 46 "https://crbug.com/dawn/145"}}, 47 {Toggle::AlwaysResolveIntoZeroLevelAndLayer, 48 {"always_resolve_into_zero_level_and_layer", 49 "When the resolve target is a texture view that is created on the non-zero level or " 50 "layer of a texture, we first resolve into a temporarily 2D texture with only one " 51 "mipmap level and one array layer, and copy the result of MSAA resolve into the " 52 "true resolve target. This workaround is enabled by default on the Metal drivers " 53 "that have bugs when setting non-zero resolveLevel or resolveSlice.", 54 "https://crbug.com/dawn/56"}}, 55 {Toggle::LazyClearResourceOnFirstUse, 56 {"lazy_clear_resource_on_first_use", 57 "Clears resource to zero on first usage. This initializes the resource " 58 "so that no dirty bits from recycled memory is present in the new resource.", 59 "https://crbug.com/dawn/145"}}, 60 {Toggle::TurnOffVsync, 61 {"turn_off_vsync", 62 "Turn off vsync when rendering. In order to do performance test or run perf tests, " 63 "turn off vsync so that the fps can exeed 60.", 64 "https://crbug.com/dawn/237"}}, 65 {Toggle::UseTemporaryBufferInCompressedTextureToTextureCopy, 66 {"use_temporary_buffer_in_texture_to_texture_copy", 67 "Split texture-to-texture copy into two copies: copy from source texture into a " 68 "temporary buffer, and copy from the temporary buffer into the destination texture " 69 "when copying between compressed textures that don't have block-aligned sizes. This " 70 "workaround is enabled by default on all Vulkan drivers to solve an issue in the " 71 "Vulkan SPEC about the texture-to-texture copies with compressed formats. See #1005 " 72 "(https://github.com/KhronosGroup/Vulkan-Docs/issues/1005) for more details.", 73 "https://crbug.com/dawn/42"}}, 74 {Toggle::UseD3D12ResourceHeapTier2, 75 {"use_d3d12_resource_heap_tier2", 76 "Enable support for resource heap tier 2. Resource heap tier 2 allows mixing of " 77 "texture and buffers in the same heap. This allows better heap re-use and reduces " 78 "fragmentation.", 79 "https://crbug.com/dawn/27"}}, 80 {Toggle::UseD3D12RenderPass, 81 {"use_d3d12_render_pass", 82 "Use the D3D12 render pass API introduced in Windows build 1809 by default. On " 83 "versions of Windows prior to build 1809, or when this toggle is turned off, Dawn " 84 "will emulate a render pass.", 85 "https://crbug.com/dawn/36"}}, 86 {Toggle::UseD3D12ResidencyManagement, 87 {"use_d3d12_residency_management", 88 "Enable residency management. This allows page-in and page-out of resource heaps in " 89 "GPU memory. This component improves overcommitted performance by keeping the most " 90 "recently used resources local to the GPU. Turning this component off can cause " 91 "allocation failures when application memory exceeds physical device memory.", 92 "https://crbug.com/dawn/193"}}, 93 {Toggle::SkipValidation, 94 {"skip_validation", "Skip expensive validation of Dawn commands.", 95 "https://crbug.com/dawn/271"}}, 96 {Toggle::VulkanUseD32S8, 97 {"vulkan_use_d32s8", 98 "Vulkan mandates support of either D32_FLOAT_S8 or D24_UNORM_S8. When available the " 99 "backend will use D32S8 (toggle to on) but setting the toggle to off will make it" 100 "use the D24S8 format when possible.", 101 "https://crbug.com/dawn/286"}}, 102 {Toggle::MetalDisableSamplerCompare, 103 {"metal_disable_sampler_compare", 104 "Disables the use of sampler compare on Metal. This is unsupported before A9 " 105 "processors.", 106 "https://crbug.com/dawn/342"}}, 107 {Toggle::MetalUseSharedModeForCounterSampleBuffer, 108 {"metal_use_shared_mode_for_counter_sample_buffer", 109 "The query set on Metal need to create MTLCounterSampleBuffer which storage mode " 110 "must be either MTLStorageModeShared or MTLStorageModePrivate. But the private mode " 111 "does not work properly on Intel platforms. The workaround is use shared mode " 112 "instead.", 113 "https://crbug.com/dawn/434"}}, 114 {Toggle::DisableBaseVertex, 115 {"disable_base_vertex", 116 "Disables the use of non-zero base vertex which is unsupported on some platforms.", 117 "https://crbug.com/dawn/343"}}, 118 {Toggle::DisableBaseInstance, 119 {"disable_base_instance", 120 "Disables the use of non-zero base instance which is unsupported on some " 121 "platforms.", 122 "https://crbug.com/dawn/343"}}, 123 {Toggle::DisableIndexedDrawBuffers, 124 {"disable_indexed_draw_buffers", 125 "Disables the use of indexed draw buffer state which is unsupported on some " 126 "platforms.", 127 "https://crbug.com/dawn/582"}}, 128 {Toggle::DisableSnormRead, 129 {"disable_snorm_read", 130 "Disables reading from Snorm textures which is unsupported on some platforms.", 131 "https://crbug.com/dawn/667"}}, 132 {Toggle::DisableDepthStencilRead, 133 {"disable_depth_stencil_read", 134 "Disables reading from depth/stencil textures which is unsupported on some " 135 "platforms.", 136 "https://crbug.com/dawn/667"}}, 137 {Toggle::DisableSampleVariables, 138 {"disable_sample_variables", 139 "Disables gl_SampleMask and related functionality which is unsupported on some " 140 "platforms.", 141 "https://crbug.com/dawn/673"}}, 142 {Toggle::UseD3D12SmallShaderVisibleHeapForTesting, 143 {"use_d3d12_small_shader_visible_heap", 144 "Enable use of a small D3D12 shader visible heap, instead of using a large one by " 145 "default. This setting is used to test bindgroup encoding.", 146 "https://crbug.com/dawn/155"}}, 147 {Toggle::UseDXC, 148 {"use_dxc", 149 "Use DXC instead of FXC for compiling HLSL when both dxcompiler.dll and dxil.dll " 150 "is available.", 151 "https://crbug.com/dawn/402"}}, 152 {Toggle::DisableRobustness, 153 {"disable_robustness", "Disable robust buffer access", "https://crbug.com/dawn/480"}}, 154 {Toggle::MetalEnableVertexPulling, 155 {"metal_enable_vertex_pulling", 156 "Uses vertex pulling to protect out-of-bounds reads on Metal", 157 "https://crbug.com/dawn/480"}}, 158 {Toggle::DisallowUnsafeAPIs, 159 {"disallow_unsafe_apis", 160 "Produces validation errors on API entry points or parameter combinations that " 161 "aren't considered secure yet.", 162 "http://crbug.com/1138528"}}, 163 {Toggle::FlushBeforeClientWaitSync, 164 {"flush_before_client_wait_sync", 165 "Call glFlush before glClientWaitSync to work around bugs in the latter", 166 "https://crbug.com/dawn/633"}}, 167 {Toggle::UseTempBufferInSmallFormatTextureToTextureCopyFromGreaterToLessMipLevel, 168 {"use_temp_buffer_in_small_format_texture_to_texture_copy_from_greater_to_less_mip_" 169 "level", 170 "Split texture-to-texture copy into two copies: copy from source texture into a " 171 "temporary buffer, and copy from the temporary buffer into the destination texture " 172 "under specific situations. This workaround is by default enabled on some Intel " 173 "GPUs which have a driver bug in the execution of CopyTextureRegion() when we copy " 174 "with the formats whose texel block sizes are less than 4 bytes from a greater mip " 175 "level to a smaller mip level on D3D12 backends.", 176 "https://crbug.com/1161355"}}, 177 {Toggle::EmitHLSLDebugSymbols, 178 {"emit_hlsl_debug_symbols", 179 "Sets the D3DCOMPILE_SKIP_OPTIMIZATION and D3DCOMPILE_DEBUG compilation flags when " 180 "compiling HLSL code. Enables better shader debugging with external graphics " 181 "debugging tools.", 182 "https://crbug.com/dawn/776"}}, 183 {Toggle::DisallowSpirv, 184 {"disallow_spirv", 185 "Disallow usage of SPIR-V completely so that only WGSL is used for shader modules." 186 "This is useful to prevent a Chromium renderer process from successfully sending" 187 "SPIR-V code to be compiled in the GPU process.", 188 "https://crbug.com/1214923"}}, 189 {Toggle::DumpShaders, 190 {"dump_shaders", 191 "Dump shaders for debugging purposes. Dumped shaders will be log via " 192 "EmitLog, thus printed in Chrome console or consumed by user-defined callback " 193 "function.", 194 "https://crbug.com/dawn/792"}}, 195 {Toggle::DEPRECATED_DumpTranslatedShaders, 196 {"dump_translated_shaders", "Deprecated. Use dump_shaders", 197 "https://crbug.com/dawn/792"}}, 198 {Toggle::ForceWGSLStep, 199 {"force_wgsl_step", 200 "When ingesting SPIR-V shaders, force a first conversion to WGSL. This allows " 201 "testing Tint's SPIRV->WGSL translation on real content to be sure that it will " 202 "work when the same translation runs in a WASM module in the page.", 203 "https://crbug.com/dawn/960"}}, 204 {Toggle::DisableWorkgroupInit, 205 {"disable_workgroup_init", 206 "Disables the workgroup memory zero-initialization for compute shaders.", 207 "https://crbug.com/tint/1003"}}, 208 {Toggle::DisableSymbolRenaming, 209 {"disable_symbol_renaming", 210 "Disables the WGSL symbol renaming so that names are preserved.", 211 "https://crbug.com/dawn/1016"}}, 212 {Toggle::UseUserDefinedLabelsInBackend, 213 {"use_user_defined_labels_in_backend", 214 "Enables calls to SetLabel to be forwarded to backend-specific APIs that label " 215 "objects.", 216 "https://crbug.com/dawn/840"}}, 217 {Toggle::DisableR8RG8Mipmaps, 218 {"disable_r8_rg8_mipmaps", 219 "Disables mipmaps for r8unorm and rg8unorm textures, which are known on some drivers " 220 "to not clear correctly.", 221 "https://crbug.com/dawn/1071"}}, 222 {Toggle::UseDummyFragmentInVertexOnlyPipeline, 223 {"use_dummy_fragment_in_vertex_only_pipeline", 224 "Use a dummy empty fragment shader in vertex only render pipeline. This toggle must " 225 "be enabled for OpenGL ES backend, and serves as a workaround by default enabled on " 226 "some Metal devices with Intel GPU to ensure the depth result is correct.", 227 "https://crbug.com/dawn/136"}}, 228 {Toggle::FxcOptimizations, 229 {"fxc_optimizations", 230 "Enable optimizations when compiling with FXC. Disabled by default because FXC " 231 "miscompiles in many cases when optimizations are enabled.", 232 "https://crbug.com/dawn/1203"}}, 233 234 // Dummy comment to separate the }} so it is clearer what to copy-paste to add a toggle. 235 }}; 236 } // anonymous namespace 237 Set(Toggle toggle,bool enabled)238 void TogglesSet::Set(Toggle toggle, bool enabled) { 239 if (toggle == Toggle::DEPRECATED_DumpTranslatedShaders) { 240 Set(Toggle::DumpShaders, enabled); 241 return; 242 } 243 ASSERT(toggle != Toggle::InvalidEnum); 244 const size_t toggleIndex = static_cast<size_t>(toggle); 245 toggleBitset.set(toggleIndex, enabled); 246 } 247 Has(Toggle toggle) const248 bool TogglesSet::Has(Toggle toggle) const { 249 if (toggle == Toggle::DEPRECATED_DumpTranslatedShaders) { 250 return Has(Toggle::DumpShaders); 251 } 252 ASSERT(toggle != Toggle::InvalidEnum); 253 const size_t toggleIndex = static_cast<size_t>(toggle); 254 return toggleBitset.test(toggleIndex); 255 } 256 GetContainedToggleNames() const257 std::vector<const char*> TogglesSet::GetContainedToggleNames() const { 258 std::vector<const char*> togglesNameInUse(toggleBitset.count()); 259 260 uint32_t index = 0; 261 for (uint32_t i : IterateBitSet(toggleBitset)) { 262 const char* toggleName = ToggleEnumToName(static_cast<Toggle>(i)); 263 togglesNameInUse[index] = toggleName; 264 ++index; 265 } 266 267 return togglesNameInUse; 268 } 269 ToggleEnumToName(Toggle toggle)270 const char* ToggleEnumToName(Toggle toggle) { 271 ASSERT(toggle != Toggle::InvalidEnum); 272 273 const ToggleEnumAndInfo& toggleNameAndInfo = 274 kToggleNameAndInfoList[static_cast<size_t>(toggle)]; 275 ASSERT(toggleNameAndInfo.toggle == toggle); 276 return toggleNameAndInfo.info.name; 277 } 278 GetToggleInfo(const char * toggleName)279 const ToggleInfo* TogglesInfo::GetToggleInfo(const char* toggleName) { 280 ASSERT(toggleName); 281 282 EnsureToggleNameToEnumMapInitialized(); 283 284 const auto& iter = mToggleNameToEnumMap.find(toggleName); 285 if (iter != mToggleNameToEnumMap.cend()) { 286 return &kToggleNameAndInfoList[static_cast<size_t>(iter->second)].info; 287 } 288 return nullptr; 289 } 290 ToggleNameToEnum(const char * toggleName)291 Toggle TogglesInfo::ToggleNameToEnum(const char* toggleName) { 292 ASSERT(toggleName); 293 294 EnsureToggleNameToEnumMapInitialized(); 295 296 const auto& iter = mToggleNameToEnumMap.find(toggleName); 297 if (iter != mToggleNameToEnumMap.cend()) { 298 return kToggleNameAndInfoList[static_cast<size_t>(iter->second)].toggle; 299 } 300 return Toggle::InvalidEnum; 301 } 302 EnsureToggleNameToEnumMapInitialized()303 void TogglesInfo::EnsureToggleNameToEnumMapInitialized() { 304 if (mToggleNameToEnumMapInitialized) { 305 return; 306 } 307 308 for (size_t index = 0; index < kToggleNameAndInfoList.size(); ++index) { 309 const ToggleEnumAndInfo& toggleNameAndInfo = kToggleNameAndInfoList[index]; 310 ASSERT(index == static_cast<size_t>(toggleNameAndInfo.toggle)); 311 mToggleNameToEnumMap[toggleNameAndInfo.info.name] = toggleNameAndInfo.toggle; 312 } 313 314 mToggleNameToEnumMapInitialized = true; 315 } 316 317 } // namespace dawn_native 318