[dawn] Dump shaders on failure toggle

This change introduces "dump_shaders_on_failure" toggle.
Internally this only currently applies to the d3d backends but it
could apply to others in the future.

Bug: 429187478
Change-Id: I9051b541b1249d3fb142253f619002df43b5243f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/250754
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Peter McNeeley <petermcneeley@google.com>
diff --git a/src/dawn/native/Toggles.cpp b/src/dawn/native/Toggles.cpp
index 0ca42ea..2eb4aae 100644
--- a/src/dawn/native/Toggles.cpp
+++ b/src/dawn/native/Toggles.cpp
@@ -211,6 +211,11 @@
       "Dump shaders for debugging purposes. Dumped shaders will be log via EmitLog, thus printed "
       "in Chrome console or consumed by user-defined callback function.",
       "https://crbug.com/dawn/792", ToggleStage::Device}},
+    {Toggle::DumpShadersOnFailure,
+     {"dump_shaders_on_failure",
+      "Dump shaders only on failure. Used for logging purposes. Dumped shaders will be log via "
+      "EmitLog, thus printed in Chrome console or consumed by user-defined callback function.",
+      "https://crbug.com/dawn/792", ToggleStage::Device}},
     {Toggle::DisableWorkgroupInit,
      {"disable_workgroup_init",
       "Disables the workgroup memory zero-initialization for compute shaders.",
diff --git a/src/dawn/native/Toggles.h b/src/dawn/native/Toggles.h
index 9368ae1..7d96451 100644
--- a/src/dawn/native/Toggles.h
+++ b/src/dawn/native/Toggles.h
@@ -74,6 +74,7 @@
     EmitHLSLDebugSymbols,
     DisallowSpirv,
     DumpShaders,
+    DumpShadersOnFailure,
     DisableWorkgroupInit,
     DisableDemoteToHelper,
     VulkanUseDemoteToHelperInvocationExtension,
diff --git a/src/dawn/native/d3d/D3DCompilationRequest.h b/src/dawn/native/d3d/D3DCompilationRequest.h
index 5080eb0..04c4056 100644
--- a/src/dawn/native/d3d/D3DCompilationRequest.h
+++ b/src/dawn/native/d3d/D3DCompilationRequest.h
@@ -78,7 +78,8 @@
     X(UnsafeUnserializedValue<LimitsForCompilationRequest>, adapterSupportedLimits)  \
     X(uint32_t, maxSubgroupSize)                                                     \
     X(bool, disableSymbolRenaming)                                                   \
-    X(bool, dumpShaders)
+    X(bool, dumpShaders)                                                             \
+    X(bool, dumpShadersOnFailure)
 
 #define D3D_BYTECODE_COMPILATION_REQUEST_MEMBERS(X)      \
     X(bool, hasShaderF16Feature)                         \
diff --git a/src/dawn/native/d3d/ShaderUtils.cpp b/src/dawn/native/d3d/ShaderUtils.cpp
index 3724664..1f6eda5 100644
--- a/src/dawn/native/d3d/ShaderUtils.cpp
+++ b/src/dawn/native/d3d/ShaderUtils.cpp
@@ -144,7 +144,7 @@
 ResultOrError<ComPtr<IDxcBlob>> CompileShaderDXC(const d3d::D3DBytecodeCompilationRequest& r,
                                                  const std::string& entryPointName,
                                                  const std::string& hlslSource,
-                                                 bool dumpShaders) {
+                                                 bool dumpShadersOnFailure) {
     DxcBuffer dxcBuffer;
     dxcBuffer.Ptr = hlslSource.c_str();
     dxcBuffer.Size = hlslSource.length();
@@ -170,7 +170,7 @@
         ComPtr<IDxcBlobEncoding> errors;
         DAWN_TRY(CheckHRESULT(result->GetErrorBuffer(&errors), "DXC get error buffer"));
 
-        if (dumpShaders) {
+        if (dumpShadersOnFailure) {
             return DAWN_VALIDATION_ERROR(
                 "DXC compile failed with error: %s msg: %s\n/* Generated HLSL: */\n%s\n",
                 hrAsString, static_cast<char*>(errors->GetBufferPointer()), hlslSource.c_str());
@@ -186,7 +186,7 @@
 ResultOrError<ComPtr<ID3DBlob>> CompileShaderFXC(const d3d::D3DBytecodeCompilationRequest& r,
                                                  const std::string& entryPointName,
                                                  const std::string& hlslSource,
-                                                 bool dumpShaders) {
+                                                 bool dumpShadersOnFailure) {
     ComPtr<ID3DBlob> compiledShader;
     ComPtr<ID3DBlob> errors;
 
@@ -196,7 +196,7 @@
 
     if (FAILED(result)) {
         const char* resultAsString = HRESULTAsString(result);
-        if (dumpShaders) {
+        if (dumpShadersOnFailure) {
             std::string errorMsg = errors ? static_cast<char*>(errors->GetBufferPointer()) : "";
             return DAWN_VALIDATION_ERROR(
                 "FXC compile failed with error: %s msg: %s\n/* Generated HLSL: */\n%s\n",
@@ -356,7 +356,7 @@
 
 ResultOrError<CompiledShader> CompileShader(d3d::D3DCompilationRequest r) {
     CompiledShader compiledShader;
-    bool dumpShaders = r.hlsl.dumpShaders;
+    bool dumpShadersOnFailure = r.hlsl.dumpShaders || r.hlsl.dumpShadersOnFailure;
     // Compile the source shader to HLSL.
     DAWN_TRY(TranslateToHLSL(std::move(r.hlsl), r.tracePlatform, &compiledShader));
 
@@ -367,7 +367,7 @@
             DAWN_TRY_ASSIGN(
                 compiledDXCShader,
                 CompileShaderDXC(r.bytecode, r.hlsl.tintOptions.remapped_entry_point_name,
-                                 compiledShader.hlslSource, dumpShaders));
+                                 compiledShader.hlslSource, dumpShadersOnFailure));
             compiledShader.shaderBlob = CreateBlob(std::move(compiledDXCShader));
             break;
         }
@@ -377,7 +377,7 @@
             DAWN_TRY_ASSIGN(
                 compiledFXCShader,
                 CompileShaderFXC(r.bytecode, r.hlsl.tintOptions.remapped_entry_point_name,
-                                 compiledShader.hlslSource, dumpShaders));
+                                 compiledShader.hlslSource, dumpShadersOnFailure));
             compiledShader.shaderBlob = CreateBlob(std::move(compiledFXCShader));
             break;
         }
@@ -385,7 +385,7 @@
 
     // If dumpShaders is false, we don't need the HLSL for logging. Clear the contents so it
     // isn't stored into the cache.
-    if (!dumpShaders) {
+    if (!r.hlsl.dumpShaders) {
         compiledShader.hlslSource = "";
     }
     return compiledShader;
diff --git a/src/dawn/native/d3d11/ShaderModuleD3D11.cpp b/src/dawn/native/d3d11/ShaderModuleD3D11.cpp
index 49677a5..d9f8350 100644
--- a/src/dawn/native/d3d11/ShaderModuleD3D11.cpp
+++ b/src/dawn/native/d3d11/ShaderModuleD3D11.cpp
@@ -92,6 +92,7 @@
     req.hlsl.shaderModel = 50;
     req.hlsl.disableSymbolRenaming = device->IsToggleEnabled(Toggle::DisableSymbolRenaming);
     req.hlsl.dumpShaders = device->IsToggleEnabled(Toggle::DumpShaders);
+    req.hlsl.dumpShadersOnFailure = device->IsToggleEnabled(Toggle::DumpShadersOnFailure);
     req.hlsl.tintOptions.remapped_entry_point_name = device->GetIsolatedEntryPointName();
 
     req.bytecode.hasShaderF16Feature = false;
diff --git a/src/dawn/native/d3d12/ShaderModuleD3D12.cpp b/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
index c2dd378..56ced4f 100644
--- a/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
+++ b/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
@@ -135,6 +135,7 @@
                                ->GetAppliedShaderModelUnderToggles(device->GetTogglesState());
     req.hlsl.disableSymbolRenaming = device->IsToggleEnabled(Toggle::DisableSymbolRenaming);
     req.hlsl.dumpShaders = device->IsToggleEnabled(Toggle::DumpShaders);
+    req.hlsl.dumpShadersOnFailure = device->IsToggleEnabled(Toggle::DumpShadersOnFailure);
     req.hlsl.tintOptions.remapped_entry_point_name = device->GetIsolatedEntryPointName();
 
     req.bytecode.hasShaderF16Feature = device->HasFeature(Feature::ShaderF16);