Adds new BlobCache "re-declaration" of PersistentCache.

- Note: goal is to merge the two into the same class, but to avoid breaking/fixing the current D3D12 shader caching, introducing a new one, and will merge the old one later on.
- Adds instance of BlobCache to the Instance, and passthrough for the Device to get to it. (We want the cache to be at the Instance so that eventually different devices can still use the cache (assuming same isolation key)).

Bug: dawn:549
Change-Id: Ib7c82a439f32b306f0cccd3db424fb0e427a90a1
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/86400
Reviewed-by: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Loko Kung <lokokung@google.com>
This commit is contained in:
Loko Kung 2022-04-20 23:56:25 +00:00 committed by Dawn LUCI CQ
parent 775fee6b6a
commit 6d9b322958
8 changed files with 214 additions and 5 deletions

View File

@ -202,6 +202,8 @@ source_set("sources") {
"BindGroupTracker.h",
"BindingInfo.cpp",
"BindingInfo.h",
"BlobCache.cpp",
"BlobCache.h",
"BuddyAllocator.cpp",
"BuddyAllocator.h",
"BuddyMemoryAllocator.cpp",

View File

@ -0,0 +1,93 @@
// Copyright 2022 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "dawn/native/BlobCache.h"
#include "dawn/common/Assert.h"
#include "dawn/native/CacheKey.h"
#include "dawn/native/Instance.h"
#include "dawn/platform/DawnPlatform.h"
namespace dawn::native {
CachedBlob::CachedBlob(size_t size) {
if (size != 0) {
Reset(size);
}
}
bool CachedBlob::Empty() const {
return mSize == 0;
}
const uint8_t* CachedBlob::Data() const {
return mData.get();
}
uint8_t* CachedBlob::Data() {
return mData.get();
}
size_t CachedBlob::Size() const {
return mSize;
}
void CachedBlob::Reset(size_t size) {
mSize = size;
mData = std::make_unique<uint8_t[]>(size);
}
BlobCache::BlobCache(dawn::platform::CachingInterface* cachingInterface)
: mCache(cachingInterface) {
}
CachedBlob BlobCache::Load(const CacheKey& key) {
std::lock_guard<std::mutex> lock(mMutex);
return LoadInternal(key);
}
void BlobCache::Store(const CacheKey& key, size_t valueSize, const void* value) {
std::lock_guard<std::mutex> lock(mMutex);
StoreInternal(key, valueSize, value);
}
void BlobCache::Store(const CacheKey& key, const CachedBlob& value) {
Store(key, value.Size(), value.Data());
}
CachedBlob BlobCache::LoadInternal(const CacheKey& key) {
CachedBlob result;
if (mCache == nullptr) {
return result;
}
const size_t expectedSize = mCache->LoadData(nullptr, key.data(), key.size(), nullptr, 0);
if (expectedSize > 0) {
result.Reset(expectedSize);
const size_t actualSize =
mCache->LoadData(nullptr, key.data(), key.size(), result.Data(), expectedSize);
ASSERT(expectedSize == actualSize);
}
return result;
}
void BlobCache::StoreInternal(const CacheKey& key, size_t valueSize, const void* value) {
ASSERT(value != nullptr);
ASSERT(valueSize > 0);
if (mCache == nullptr) {
return;
}
mCache->StoreData(nullptr, key.data(), key.size(), value, valueSize);
}
} // namespace dawn::native

View File

@ -0,0 +1,80 @@
// Copyright 2022 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_DAWN_NATIVE_BLOBCACHE_H_
#define SRC_DAWN_NATIVE_BLOBCACHE_H_
#include <memory>
#include <mutex>
namespace dawn::platform {
class CachingInterface;
}
namespace dawn::native {
class BlobCache;
class CacheKey;
class InstanceBase;
class CachedBlob {
public:
explicit CachedBlob(size_t size = 0);
bool Empty() const;
const uint8_t* Data() const;
uint8_t* Data();
size_t Size() const;
void Reset(size_t size);
private:
std::unique_ptr<uint8_t[]> mData = nullptr;
size_t mSize = 0;
};
// This class should always be thread-safe because it may be called asynchronously. Its purpose
// is to wrap the CachingInterface provided via a platform.
// TODO(dawn:549): This is a "re-declaration" of the current PersistentCache since there are
// some dependencies on that one for the semi-implemented D3D12 shader cache and some changes
// introduced here are breaking. Eventually the goal is to unify the two, but for development
// purposes, we are splitting these for now and will re-merge them in a later change.
class BlobCache {
public:
explicit BlobCache(dawn::platform::CachingInterface* cachingInterface = nullptr);
// Returns empty blob if the key is not found in the cache.
CachedBlob Load(const CacheKey& key);
// Value to store must be non-empty/non-null.
void Store(const CacheKey& key, size_t valueSize, const void* value);
void Store(const CacheKey& key, const CachedBlob& value);
private:
// Non-thread safe internal implementations of load and store. Exposed callers that use
// these helpers need to make sure that these are entered with `mMutex` held.
CachedBlob LoadInternal(const CacheKey& key);
void StoreInternal(const CacheKey& key, size_t valueSize, const void* value);
// Protects thread safety of access to mCache.
std::mutex mMutex;
// TODO(dawn:549): Current CachingInterface declaration requires passing a device to each
// call, but this might be unnecessary. This class just passes nullptr for those calls
// right now. Eventually we can just change the interface to be more generic.
dawn::platform::CachingInterface* mCache;
};
} // namespace dawn::native
#endif // SRC_DAWN_NATIVE_BLOBCACHE_H_

View File

@ -45,6 +45,8 @@ target_sources(dawn_native PRIVATE
"BindGroupTracker.h"
"BindingInfo.cpp"
"BindingInfo.h"
"BlobCache.cpp"
"BlobCache.h"
"BuddyAllocator.cpp"
"BuddyAllocator.h"
"BuddyMemoryAllocator.cpp"

View File

@ -25,6 +25,7 @@
#include "dawn/native/AttachmentState.h"
#include "dawn/native/BindGroup.h"
#include "dawn/native/BindGroupLayout.h"
#include "dawn/native/BlobCache.h"
#include "dawn/native/Buffer.h"
#include "dawn/native/ChainUtils_autogen.h"
#include "dawn/native/CommandBuffer.h"
@ -578,6 +579,10 @@ namespace dawn::native {
return mPersistentCache.get();
}
BlobCache* DeviceBase::GetBlobCache() {
return mInstance->GetBlobCache();
}
MaybeError DeviceBase::ValidateObject(const ApiObjectBase* object) const {
ASSERT(object != nullptr);
DAWN_INVALID_IF(object->GetDevice() != this,

View File

@ -42,18 +42,15 @@ namespace dawn::platform {
} // namespace dawn::platform
namespace dawn::native {
class AdapterBase;
class AsyncTaskManager;
class AttachmentState;
class AttachmentStateBlueprint;
class BindGroupLayoutBase;
class BlobCache;
class CallbackTaskManager;
class DynamicUploader;
class ErrorScopeStack;
class ExternalTextureBase;
class OwnedCompilationMessages;
class PersistentCache;
class StagingBufferBase;
struct CallbackTask;
struct InternalPipelineStore;
struct ShaderModuleParseResult;
@ -279,7 +276,9 @@ namespace dawn::native {
MaybeError ValidateIsAlive() const;
// TODO(dawn:549): Deprecate PersistentCache, once it's usage in D3D12 shaders is removed.
PersistentCache* GetPersistentCache();
BlobCache* GetBlobCache();
virtual ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(
size_t size) = 0;
@ -546,6 +545,7 @@ namespace dawn::native {
std::unique_ptr<InternalPipelineStore> mInternalPipelineStore;
// TODO(dawn:549): Deprecate PersistentCache, once it's usage in D3D12 shaders is removed.
std::unique_ptr<PersistentCache> mPersistentCache;
std::unique_ptr<CallbackTaskManager> mCallbackTaskManager;

View File

@ -93,6 +93,14 @@ namespace dawn::native {
return enabledBackends;
}
dawn::platform::CachingInterface* GetCachingInterface(dawn::platform::Platform* platform) {
if (platform != nullptr) {
return platform->GetCachingInterface(/*fingerprint*/ nullptr,
/*fingerprintSize*/ 0);
}
return nullptr;
}
} // anonymous namespace
InstanceBase* APICreateInstance(const InstanceDescriptor* descriptor) {
@ -133,6 +141,11 @@ namespace dawn::native {
mRuntimeSearchPaths.push_back(std::move(*p));
}
mRuntimeSearchPaths.push_back("");
// Initialize the platform to the default for now.
mDefaultPlatform = std::make_unique<dawn::platform::Platform>();
SetPlatform(mDefaultPlatform.get());
return {};
}
@ -401,7 +414,12 @@ namespace dawn::native {
}
void InstanceBase::SetPlatform(dawn::platform::Platform* platform) {
mPlatform = platform;
if (platform == nullptr) {
mPlatform = mDefaultPlatform.get();
} else {
mPlatform = platform;
}
mBlobCache = std::make_unique<BlobCache>(GetCachingInterface(platform));
}
dawn::platform::Platform* InstanceBase::GetPlatform() {
@ -415,6 +433,10 @@ namespace dawn::native {
return mDefaultPlatform.get();
}
BlobCache* InstanceBase::GetBlobCache() {
return mBlobCache.get();
}
const std::vector<std::string>& InstanceBase::GetRuntimeSearchPaths() const {
return mRuntimeSearchPaths;
}

View File

@ -25,6 +25,7 @@
#include "dawn/common/ityp_bitset.h"
#include "dawn/native/Adapter.h"
#include "dawn/native/BackendConnection.h"
#include "dawn/native/BlobCache.h"
#include "dawn/native/Features.h"
#include "dawn/native/Toggles.h"
#include "dawn/native/dawn_platform.h"
@ -76,8 +77,11 @@ namespace dawn::native {
void EnableBeginCaptureOnStartup(bool beginCaptureOnStartup);
bool IsBeginCaptureOnStartupEnabled() const;
// TODO(dawn:1374): SetPlatform should become a private helper, and a NOT thread-safe
// testing version exposed for special testing cases.
void SetPlatform(dawn::platform::Platform* platform);
dawn::platform::Platform* GetPlatform();
BlobCache* GetBlobCache();
const std::vector<std::string>& GetRuntimeSearchPaths() const;
@ -115,6 +119,7 @@ namespace dawn::native {
dawn::platform::Platform* mPlatform = nullptr;
std::unique_ptr<dawn::platform::Platform> mDefaultPlatform;
std::unique_ptr<BlobCache> mBlobCache;
std::vector<std::unique_ptr<BackendConnection>> mBackends;
std::vector<Ref<AdapterBase>> mAdapters;