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::DisableResourceSuballocation, 94 {"disable_resource_suballocation", 95 "Force the backends to not perform resource suballocation. This may expose " 96 "allocation " 97 "patterns which would otherwise only occur with large or specific types of " 98 "resources.", 99 "https://crbug.com/1313172"}}, 100 {Toggle::SkipValidation, 101 {"skip_validation", "Skip expensive validation of Dawn commands.", 102 "https://crbug.com/dawn/271"}}, 103 {Toggle::VulkanUseD32S8, 104 {"vulkan_use_d32s8", 105 "Vulkan mandates support of either D32_FLOAT_S8 or D24_UNORM_S8. When available the " 106 "backend will use D32S8 (toggle to on) but setting the toggle to off will make it" 107 "use the D24S8 format when possible.", 108 "https://crbug.com/dawn/286"}}, 109 {Toggle::MetalDisableSamplerCompare, 110 {"metal_disable_sampler_compare", 111 "Disables the use of sampler compare on Metal. This is unsupported before A9 " 112 "processors.", 113 "https://crbug.com/dawn/342"}}, 114 {Toggle::MetalUseSharedModeForCounterSampleBuffer, 115 {"metal_use_shared_mode_for_counter_sample_buffer", 116 "The query set on Metal need to create MTLCounterSampleBuffer which storage mode " 117 "must be either MTLStorageModeShared or MTLStorageModePrivate. But the private mode " 118 "does not work properly on Intel platforms. The workaround is use shared mode " 119 "instead.", 120 "https://crbug.com/dawn/434"}}, 121 {Toggle::DisableBaseVertex, 122 {"disable_base_vertex", 123 "Disables the use of non-zero base vertex which is unsupported on some platforms.", 124 "https://crbug.com/dawn/343"}}, 125 {Toggle::DisableBaseInstance, 126 {"disable_base_instance", 127 "Disables the use of non-zero base instance which is unsupported on some " 128 "platforms.", 129 "https://crbug.com/dawn/343"}}, 130 {Toggle::DisableIndexedDrawBuffers, 131 {"disable_indexed_draw_buffers", 132 "Disables the use of indexed draw buffer state which is unsupported on some " 133 "platforms.", 134 "https://crbug.com/dawn/582"}}, 135 {Toggle::DisableSnormRead, 136 {"disable_snorm_read", 137 "Disables reading from Snorm textures which is unsupported on some platforms.", 138 "https://crbug.com/dawn/667"}}, 139 {Toggle::DisableDepthStencilRead, 140 {"disable_depth_stencil_read", 141 "Disables reading from depth/stencil textures which is unsupported on some " 142 "platforms.", 143 "https://crbug.com/dawn/667"}}, 144 {Toggle::DisableSampleVariables, 145 {"disable_sample_variables", 146 "Disables gl_SampleMask and related functionality which is unsupported on some " 147 "platforms.", 148 "https://crbug.com/dawn/673"}}, 149 {Toggle::UseD3D12SmallShaderVisibleHeapForTesting, 150 {"use_d3d12_small_shader_visible_heap", 151 "Enable use of a small D3D12 shader visible heap, instead of using a large one by " 152 "default. This setting is used to test bindgroup encoding.", 153 "https://crbug.com/dawn/155"}}, 154 {Toggle::UseDXC, 155 {"use_dxc", 156 "Use DXC instead of FXC for compiling HLSL when both dxcompiler.dll and dxil.dll " 157 "is available.", 158 "https://crbug.com/dawn/402"}}, 159 {Toggle::DisableRobustness, 160 {"disable_robustness", "Disable robust buffer access", "https://crbug.com/dawn/480"}}, 161 {Toggle::MetalEnableVertexPulling, 162 {"metal_enable_vertex_pulling", 163 "Uses vertex pulling to protect out-of-bounds reads on Metal", 164 "https://crbug.com/dawn/480"}}, 165 {Toggle::DisallowUnsafeAPIs, 166 {"disallow_unsafe_apis", 167 "Produces validation errors on API entry points or parameter combinations that " 168 "aren't considered secure yet.", 169 "http://crbug.com/1138528"}}, 170 {Toggle::FlushBeforeClientWaitSync, 171 {"flush_before_client_wait_sync", 172 "Call glFlush before glClientWaitSync to work around bugs in the latter", 173 "https://crbug.com/dawn/633"}}, 174 {Toggle::UseTempBufferInSmallFormatTextureToTextureCopyFromGreaterToLessMipLevel, 175 {"use_temp_buffer_in_small_format_texture_to_texture_copy_from_greater_to_less_mip_" 176 "level", 177 "Split texture-to-texture copy into two copies: copy from source texture into a " 178 "temporary buffer, and copy from the temporary buffer into the destination texture " 179 "under specific situations. This workaround is by default enabled on some Intel " 180 "GPUs which have a driver bug in the execution of CopyTextureRegion() when we copy " 181 "with the formats whose texel block sizes are less than 4 bytes from a greater mip " 182 "level to a smaller mip level on D3D12 backends.", 183 "https://crbug.com/1161355"}}, 184 {Toggle::EmitHLSLDebugSymbols, 185 {"emit_hlsl_debug_symbols", 186 "Sets the D3DCOMPILE_SKIP_OPTIMIZATION and D3DCOMPILE_DEBUG compilation flags when " 187 "compiling HLSL code. Enables better shader debugging with external graphics " 188 "debugging tools.", 189 "https://crbug.com/dawn/776"}}, 190 {Toggle::DisallowSpirv, 191 {"disallow_spirv", 192 "Disallow usage of SPIR-V completely so that only WGSL is used for shader modules." 193 "This is useful to prevent a Chromium renderer process from successfully sending" 194 "SPIR-V code to be compiled in the GPU process.", 195 "https://crbug.com/1214923"}}, 196 {Toggle::DumpShaders, 197 {"dump_shaders", 198 "Dump shaders for debugging purposes. Dumped shaders will be log via " 199 "EmitLog, thus printed in Chrome console or consumed by user-defined callback " 200 "function.", 201 "https://crbug.com/dawn/792"}}, 202 {Toggle::DEPRECATED_DumpTranslatedShaders, 203 {"dump_translated_shaders", "Deprecated. Use dump_shaders", 204 "https://crbug.com/dawn/792"}}, 205 {Toggle::ForceWGSLStep, 206 {"force_wgsl_step", 207 "When ingesting SPIR-V shaders, force a first conversion to WGSL. This allows " 208 "testing Tint's SPIRV->WGSL translation on real content to be sure that it will " 209 "work when the same translation runs in a WASM module in the page.", 210 "https://crbug.com/dawn/960"}}, 211 {Toggle::DisableWorkgroupInit, 212 {"disable_workgroup_init", 213 "Disables the workgroup memory zero-initialization for compute shaders.", 214 "https://crbug.com/tint/1003"}}, 215 {Toggle::DisableSymbolRenaming, 216 {"disable_symbol_renaming", 217 "Disables the WGSL symbol renaming so that names are preserved.", 218 "https://crbug.com/dawn/1016"}}, 219 {Toggle::UseUserDefinedLabelsInBackend, 220 {"use_user_defined_labels_in_backend", 221 "Enables calls to SetLabel to be forwarded to backend-specific APIs that label " 222 "objects.", 223 "https://crbug.com/dawn/840"}}, 224 {Toggle::DisableR8RG8Mipmaps, 225 {"disable_r8_rg8_mipmaps", 226 "Disables mipmaps for r8unorm and rg8unorm textures, which are known on some drivers " 227 "to not clear correctly.", 228 "https://crbug.com/dawn/1071"}}, 229 {Toggle::UseDummyFragmentInVertexOnlyPipeline, 230 {"use_dummy_fragment_in_vertex_only_pipeline", 231 "Use a dummy empty fragment shader in vertex only render pipeline. This toggle must " 232 "be enabled for OpenGL ES backend, and serves as a workaround by default enabled on " 233 "some Metal devices with Intel GPU to ensure the depth result is correct.", 234 "https://crbug.com/dawn/136"}}, 235 {Toggle::FxcOptimizations, 236 {"fxc_optimizations", 237 "Enable optimizations when compiling with FXC. Disabled by default because FXC " 238 "miscompiles in many cases when optimizations are enabled.", 239 "https://crbug.com/dawn/1203"}}, 240 241 // Dummy comment to separate the }} so it is clearer what to copy-paste to add a toggle. 242 }}; 243 } // anonymous namespace 244 Set(Toggle toggle,bool enabled)245 void TogglesSet::Set(Toggle toggle, bool enabled) { 246 if (toggle == Toggle::DEPRECATED_DumpTranslatedShaders) { 247 Set(Toggle::DumpShaders, enabled); 248 return; 249 } 250 ASSERT(toggle != Toggle::InvalidEnum); 251 const size_t toggleIndex = static_cast<size_t>(toggle); 252 toggleBitset.set(toggleIndex, enabled); 253 } 254 Has(Toggle toggle) const255 bool TogglesSet::Has(Toggle toggle) const { 256 if (toggle == Toggle::DEPRECATED_DumpTranslatedShaders) { 257 return Has(Toggle::DumpShaders); 258 } 259 ASSERT(toggle != Toggle::InvalidEnum); 260 const size_t toggleIndex = static_cast<size_t>(toggle); 261 return toggleBitset.test(toggleIndex); 262 } 263 GetContainedToggleNames() const264 std::vector<const char*> TogglesSet::GetContainedToggleNames() const { 265 std::vector<const char*> togglesNameInUse(toggleBitset.count()); 266 267 uint32_t index = 0; 268 for (uint32_t i : IterateBitSet(toggleBitset)) { 269 const char* toggleName = ToggleEnumToName(static_cast<Toggle>(i)); 270 togglesNameInUse[index] = toggleName; 271 ++index; 272 } 273 274 return togglesNameInUse; 275 } 276 ToggleEnumToName(Toggle toggle)277 const char* ToggleEnumToName(Toggle toggle) { 278 ASSERT(toggle != Toggle::InvalidEnum); 279 280 const ToggleEnumAndInfo& toggleNameAndInfo = 281 kToggleNameAndInfoList[static_cast<size_t>(toggle)]; 282 ASSERT(toggleNameAndInfo.toggle == toggle); 283 return toggleNameAndInfo.info.name; 284 } 285 GetToggleInfo(const char * toggleName)286 const ToggleInfo* TogglesInfo::GetToggleInfo(const char* toggleName) { 287 ASSERT(toggleName); 288 289 EnsureToggleNameToEnumMapInitialized(); 290 291 const auto& iter = mToggleNameToEnumMap.find(toggleName); 292 if (iter != mToggleNameToEnumMap.cend()) { 293 return &kToggleNameAndInfoList[static_cast<size_t>(iter->second)].info; 294 } 295 return nullptr; 296 } 297 ToggleNameToEnum(const char * toggleName)298 Toggle TogglesInfo::ToggleNameToEnum(const char* toggleName) { 299 ASSERT(toggleName); 300 301 EnsureToggleNameToEnumMapInitialized(); 302 303 const auto& iter = mToggleNameToEnumMap.find(toggleName); 304 if (iter != mToggleNameToEnumMap.cend()) { 305 return kToggleNameAndInfoList[static_cast<size_t>(iter->second)].toggle; 306 } 307 return Toggle::InvalidEnum; 308 } 309 EnsureToggleNameToEnumMapInitialized()310 void TogglesInfo::EnsureToggleNameToEnumMapInitialized() { 311 if (mToggleNameToEnumMapInitialized) { 312 return; 313 } 314 315 for (size_t index = 0; index < kToggleNameAndInfoList.size(); ++index) { 316 const ToggleEnumAndInfo& toggleNameAndInfo = kToggleNameAndInfoList[index]; 317 ASSERT(index == static_cast<size_t>(toggleNameAndInfo.toggle)); 318 mToggleNameToEnumMap[toggleNameAndInfo.info.name] = toggleNameAndInfo.toggle; 319 } 320 321 mToggleNameToEnumMapInitialized = true; 322 } 323 324 } // namespace dawn_native 325