Adds UMA histograms for pipeline compilations in Dawn.
- Updates Vulkan/D3D12 backends for cache hit/miss metrics.
Bugs: dawn:1934
Change-Id: Ifcb38c16ea2a67fd3c47a6b0c81dbba5c5f83d71
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/142980
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Loko Kung <lokokung@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/native/d3d12/ComputePipelineD3D12.cpp b/src/dawn/native/d3d12/ComputePipelineD3D12.cpp
index 6b962a5..8dbf5bd 100644
--- a/src/dawn/native/d3d12/ComputePipelineD3D12.cpp
+++ b/src/dawn/native/d3d12/ComputePipelineD3D12.cpp
@@ -25,6 +25,7 @@
#include "dawn/native/d3d12/PlatformFunctionsD3D12.h"
#include "dawn/native/d3d12/ShaderModuleD3D12.h"
#include "dawn/native/d3d12/UtilsD3D12.h"
+#include "dawn/platform/metrics/HistogramMacros.h"
namespace dawn::native::d3d12 {
@@ -76,7 +77,10 @@
d3dDesc.CachedPSO.CachedBlobSizeInBytes = blob.Size();
}
+ // We don't use the scoped cache histogram counters for the cache hit here so that we can
+ // condition on whether it fails appropriately.
auto* d3d12Device = device->GetD3D12Device();
+ platform::metrics::DawnHistogramTimer cacheTimer(device->GetPlatform());
HRESULT result =
d3d12Device->CreateComputePipelineState(&d3dDesc, IID_PPV_ARGS(&mPipelineState));
if (cacheHit && result == D3D12_ERROR_DRIVER_VERSION_MISMATCH) {
@@ -84,16 +88,20 @@
cacheHit = false;
d3dDesc.CachedPSO.pCachedBlob = nullptr;
d3dDesc.CachedPSO.CachedBlobSizeInBytes = 0;
+ cacheTimer.Reset();
result = d3d12Device->CreateComputePipelineState(&d3dDesc, IID_PPV_ARGS(&mPipelineState));
}
DAWN_TRY(CheckHRESULT(result, "D3D12 creating pipeline state"));
if (!cacheHit) {
// Cache misses, need to get pipeline cached blob and store.
+ cacheTimer.RecordMicroseconds("D3D12.CreateComputePipelineState.CacheMiss");
ComPtr<ID3DBlob> d3dBlob;
DAWN_TRY(CheckHRESULT(GetPipelineState()->GetCachedBlob(&d3dBlob),
"D3D12 compute pipeline state get cached blob"));
device->StoreCachedBlob(GetCacheKey(), CreateBlob(std::move(d3dBlob)));
+ } else {
+ cacheTimer.RecordMicroseconds("D3D12.CreateComputePipelineState.CacheHit");
}
SetLabelImpl();
diff --git a/src/dawn/native/d3d12/RenderPipelineD3D12.cpp b/src/dawn/native/d3d12/RenderPipelineD3D12.cpp
index 0c87835d..9b10ecc 100644
--- a/src/dawn/native/d3d12/RenderPipelineD3D12.cpp
+++ b/src/dawn/native/d3d12/RenderPipelineD3D12.cpp
@@ -30,6 +30,7 @@
#include "dawn/native/d3d12/ShaderModuleD3D12.h"
#include "dawn/native/d3d12/TextureD3D12.h"
#include "dawn/native/d3d12/UtilsD3D12.h"
+#include "dawn/platform/metrics/HistogramMacros.h"
namespace dawn::native::d3d12 {
namespace {
@@ -411,24 +412,32 @@
descriptorD3D12.CachedPSO.CachedBlobSizeInBytes = blob.Size();
}
- HRESULT result = device->GetD3D12Device()->CreateGraphicsPipelineState(
- &descriptorD3D12, IID_PPV_ARGS(&mPipelineState));
+ // We don't use the scoped cache histogram counters for the cache hit here so that we can
+ // condition on whether it fails appropriately.
+ auto* d3d12Device = device->GetD3D12Device();
+ platform::metrics::DawnHistogramTimer cacheTimer(device->GetPlatform());
+ HRESULT result =
+ d3d12Device->CreateGraphicsPipelineState(&descriptorD3D12, IID_PPV_ARGS(&mPipelineState));
if (cacheHit && result == D3D12_ERROR_DRIVER_VERSION_MISMATCH) {
// See dawn:1878 where it is possible for the PSO creation to fail with this error.
cacheHit = false;
descriptorD3D12.CachedPSO.pCachedBlob = nullptr;
descriptorD3D12.CachedPSO.CachedBlobSizeInBytes = 0;
- result = device->GetD3D12Device()->CreateGraphicsPipelineState(
- &descriptorD3D12, IID_PPV_ARGS(&mPipelineState));
+ cacheTimer.Reset();
+ result = d3d12Device->CreateGraphicsPipelineState(&descriptorD3D12,
+ IID_PPV_ARGS(&mPipelineState));
}
DAWN_TRY(CheckHRESULT(result, "D3D12 create graphics pipeline state"));
if (!cacheHit) {
// Cache misses, need to get pipeline cached blob and store.
+ cacheTimer.RecordMicroseconds("D3D12.CreateGraphicsPipelineState.CacheMiss");
ComPtr<ID3DBlob> d3dBlob;
DAWN_TRY(CheckHRESULT(GetPipelineState()->GetCachedBlob(&d3dBlob),
"D3D12 render pipeline state get cached blob"));
device->StoreCachedBlob(GetCacheKey(), CreateBlob(std::move(d3dBlob)));
+ } else {
+ cacheTimer.RecordMicroseconds("D3D12.CreateGraphicsPipelineState.CacheHit");
}
SetLabelImpl();
diff --git a/src/dawn/native/vulkan/ComputePipelineVk.cpp b/src/dawn/native/vulkan/ComputePipelineVk.cpp
index f607f7b..88cf7c4 100644
--- a/src/dawn/native/vulkan/ComputePipelineVk.cpp
+++ b/src/dawn/native/vulkan/ComputePipelineVk.cpp
@@ -26,6 +26,7 @@
#include "dawn/native/vulkan/ShaderModuleVk.h"
#include "dawn/native/vulkan/UtilsVulkan.h"
#include "dawn/native/vulkan/VulkanError.h"
+#include "dawn/platform/metrics/HistogramMacros.h"
namespace dawn::native::vulkan {
@@ -86,11 +87,22 @@
stream::Iterable(moduleAndSpirv.spirv, moduleAndSpirv.wordCount));
// Try to see if we have anything in the blob cache.
+ platform::metrics::DawnHistogramTimer cacheTimer(GetDevice()->GetPlatform());
Ref<PipelineCache> cache = ToBackend(GetDevice()->GetOrCreatePipelineCache(GetCacheKey()));
- DAWN_TRY(
- CheckVkSuccess(device->fn.CreateComputePipelines(device->GetVkDevice(), cache->GetHandle(),
- 1, &createInfo, nullptr, &*mHandle),
- "CreateComputePipeline"));
+ if (cache->CacheHit()) {
+ DAWN_TRY(CheckVkSuccess(
+ device->fn.CreateComputePipelines(device->GetVkDevice(), cache->GetHandle(), 1,
+ &createInfo, nullptr, &*mHandle),
+ "CreateComputePipelines"));
+ cacheTimer.RecordMicroseconds("Vulkan.CreateComputePipelines.CacheHit");
+ } else {
+ cacheTimer.Reset();
+ DAWN_TRY(CheckVkSuccess(
+ device->fn.CreateComputePipelines(device->GetVkDevice(), cache->GetHandle(), 1,
+ &createInfo, nullptr, &*mHandle),
+ "CreateComputePipelines"));
+ cacheTimer.RecordMicroseconds("Vulkan.CreateComputePipelines.CacheMiss");
+ }
// TODO(dawn:549): Flush is currently in the same thread, but perhaps deferrable.
DAWN_TRY(cache->FlushIfNeeded());
diff --git a/src/dawn/native/vulkan/RenderPipelineVk.cpp b/src/dawn/native/vulkan/RenderPipelineVk.cpp
index 448ef73..d6713f9 100644
--- a/src/dawn/native/vulkan/RenderPipelineVk.cpp
+++ b/src/dawn/native/vulkan/RenderPipelineVk.cpp
@@ -28,6 +28,7 @@
#include "dawn/native/vulkan/TextureVk.h"
#include "dawn/native/vulkan/UtilsVulkan.h"
#include "dawn/native/vulkan/VulkanError.h"
+#include "dawn/platform/metrics/HistogramMacros.h"
namespace dawn::native::vulkan {
@@ -558,11 +559,23 @@
StreamIn(&mCacheKey, createInfo, layout->GetCacheKey());
// Try to see if we have anything in the blob cache.
+ platform::metrics::DawnHistogramTimer cacheTimer(GetDevice()->GetPlatform());
Ref<PipelineCache> cache = ToBackend(GetDevice()->GetOrCreatePipelineCache(GetCacheKey()));
- DAWN_TRY(
- CheckVkSuccess(device->fn.CreateGraphicsPipelines(device->GetVkDevice(), cache->GetHandle(),
- 1, &createInfo, nullptr, &*mHandle),
- "CreateGraphicsPipelines"));
+ if (cache->CacheHit()) {
+ DAWN_TRY(CheckVkSuccess(
+ device->fn.CreateGraphicsPipelines(device->GetVkDevice(), cache->GetHandle(), 1,
+ &createInfo, nullptr, &*mHandle),
+ "CreateGraphicsPipelines"));
+ cacheTimer.RecordMicroseconds("Vulkan.CreateGraphicsPipelines.CacheHit");
+ } else {
+ cacheTimer.Reset();
+ DAWN_TRY(CheckVkSuccess(
+ device->fn.CreateGraphicsPipelines(device->GetVkDevice(), cache->GetHandle(), 1,
+ &createInfo, nullptr, &*mHandle),
+ "CreateGraphicsPipelines"));
+ cacheTimer.RecordMicroseconds("Vulkan.CreateGraphicsPipelines.CacheMiss");
+ }
+
// TODO(dawn:549): Flush is currently in the same thread, but perhaps deferrable.
DAWN_TRY(cache->FlushIfNeeded());