Skip building mCacheKey when not needed

RenderPipeline[Vk]::mCacheKey contains all shader SPIR-V and all the
Vulkan creation struct data. This results in a large mCacheKey size with
graphite, it's observed to be in tens of kilobytes and it quickly adds
up to megabytes for all of the RenderPipeline objects that are kept
alive.

mCacheKey is only used for serializing VkPipelineCache objects into
BlobCache. This path isn't used with the monolithic pipeline cache so
it's all unnecessary memory usage. Only need to build the cache key if
Toggle::VulkanMonolithicPipelineCache isn't enabled.

Bug: 397934765
Change-Id: I99c2a0ed819a4fe364e71aac7ef75fb470cd6102
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/227154
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Kyle Charbonneau <kylechar@google.com>
diff --git a/src/dawn/native/vulkan/ComputePipelineVk.cpp b/src/dawn/native/vulkan/ComputePipelineVk.cpp
index 0e173a89..eb3ae4a 100644
--- a/src/dawn/native/vulkan/ComputePipelineVk.cpp
+++ b/src/dawn/native/vulkan/ComputePipelineVk.cpp
@@ -55,8 +55,14 @@
     Device* device = ToBackend(GetDevice());
     PipelineLayout* layout = ToBackend(GetLayout());
 
-    // Vulkan devices need cache UUID field to be serialized into pipeline cache keys.
-    StreamIn(&mCacheKey, device->GetDeviceInfo().properties.pipelineCacheUUID);
+    // The cache key is only used for storing VkPipelineCache objects in BlobStore. That's not
+    // done with the monolithic pipeline cache so it's unnecessary work and memory usage.
+    bool buildCacheKey =
+        !device->GetTogglesState().IsEnabled(Toggle::VulkanMonolithicPipelineCache);
+    if (buildCacheKey) {
+        // Vulkan devices need cache UUID field to be serialized into pipeline cache keys.
+        StreamIn(&mCacheKey, device->GetDeviceInfo().properties.pipelineCacheUUID);
+    }
 
     // Compute pipeline doesn't have clamp depth feature.
     // TODO(crbug.com/366291600): Setting immediate data size if needed.
@@ -99,9 +105,11 @@
             VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT);
     }
 
-    // Record cache key information now since the createInfo is not stored.
-    StreamIn(&mCacheKey, createInfo, layout,
-             stream::Iterable(moduleAndSpirv.spirv, moduleAndSpirv.wordCount));
+    if (buildCacheKey) {
+        // Record cache key information now since the createInfo is not stored.
+        StreamIn(&mCacheKey, createInfo, layout,
+                 stream::Iterable(moduleAndSpirv.spirv, moduleAndSpirv.wordCount));
+    }
 
     // Try to see if we have anything in the blob cache.
     platform::metrics::DawnHistogramTimer cacheTimer(GetDevice()->GetPlatform());
diff --git a/src/dawn/native/vulkan/RenderPipelineVk.cpp b/src/dawn/native/vulkan/RenderPipelineVk.cpp
index 15a6db6..3ada762 100644
--- a/src/dawn/native/vulkan/RenderPipelineVk.cpp
+++ b/src/dawn/native/vulkan/RenderPipelineVk.cpp
@@ -353,8 +353,14 @@
     Device* device = ToBackend(GetDevice());
     PipelineLayout* layout = ToBackend(GetLayout());
 
-    // Vulkan devices need cache UUID field to be serialized into pipeline cache keys.
-    StreamIn(&mCacheKey, device->GetDeviceInfo().properties.pipelineCacheUUID);
+    // The cache key is only used for storing VkPipelineCache objects in BlobStore. That's not
+    // done with the monolithic pipeline cache so it's unnecessary work and memory usage.
+    bool buildCacheKey =
+        !device->GetTogglesState().IsEnabled(Toggle::VulkanMonolithicPipelineCache);
+    if (buildCacheKey) {
+        // Vulkan devices need cache UUID field to be serialized into pipeline cache keys.
+        StreamIn(&mCacheKey, device->GetDeviceInfo().properties.pipelineCacheUUID);
+    }
 
     // Gather list of internal immediate constants used by this pipeline
     if (UsesFragDepth() && !HasUnclippedDepth()) {
@@ -375,8 +381,10 @@
                                             ->GetHandleAndSpirv(stage, programmableStage, layout,
                                                                 emitPointSize, GetImmediateMask()));
         mHasInputAttachment = mHasInputAttachment || moduleAndSpirv.hasInputAttachment;
-        // Record cache key for each shader since it will become inaccessible later on.
-        StreamIn(&mCacheKey, stream::Iterable(moduleAndSpirv.spirv, moduleAndSpirv.wordCount));
+        if (buildCacheKey) {
+            // Record cache key for each shader since it will become inaccessible later on.
+            StreamIn(&mCacheKey, stream::Iterable(moduleAndSpirv.spirv, moduleAndSpirv.wordCount));
+        }
 
         VkPipelineShaderStageCreateInfo* shaderStage = &shaderStages[stageCount];
         shaderStage->module = moduleAndSpirv.module;
@@ -558,7 +566,9 @@
 
         query.SetSampleCount(GetSampleCount());
 
-        StreamIn(&mCacheKey, query);
+        if (buildCacheKey) {
+            StreamIn(&mCacheKey, query);
+        }
         DAWN_TRY_ASSIGN(renderPassInfo, device->GetRenderPassCache()->GetRenderPass(query));
     }
 
@@ -601,8 +611,10 @@
     //   That also means mHasInputAttachment would be removed in future.
     createInfo.subpass = mHasInputAttachment ? 0 : renderPassInfo.mainSubpass;
 
-    // Record cache key information now since createInfo is not stored.
-    StreamIn(&mCacheKey, createInfo, layout->GetCacheKey());
+    if (buildCacheKey) {
+        // Record cache key information now since createInfo is not stored.
+        StreamIn(&mCacheKey, createInfo, layout->GetCacheKey());
+    }
 
     // Try to see if we have anything in the blob cache.
     platform::metrics::DawnHistogramTimer cacheTimer(GetDevice()->GetPlatform());