diff --git a/src/dawn/native/BUILD.gn b/src/dawn/native/BUILD.gn index 4ac4e302e6..6be16af329 100644 --- a/src/dawn/native/BUILD.gn +++ b/src/dawn/native/BUILD.gn @@ -188,6 +188,8 @@ source_set("sources") { "BindGroupTracker.h", "BindingInfo.cpp", "BindingInfo.h", + "Blob.cpp", + "Blob.h", "BlobCache.cpp", "BlobCache.h", "BuddyAllocator.cpp", @@ -374,6 +376,7 @@ source_set("sources") { "d3d12/BindGroupD3D12.h", "d3d12/BindGroupLayoutD3D12.cpp", "d3d12/BindGroupLayoutD3D12.h", + "d3d12/BlobD3D12.cpp", "d3d12/BufferD3D12.cpp", "d3d12/BufferD3D12.h", "d3d12/CPUDescriptorHeapAllocationD3D12.cpp", @@ -407,7 +410,6 @@ source_set("sources") { "d3d12/NativeSwapChainImplD3D12.h", "d3d12/PageableD3D12.cpp", "d3d12/PageableD3D12.h", - "d3d12/PipelineCacheD3D12.cpp", "d3d12/PipelineLayoutD3D12.cpp", "d3d12/PipelineLayoutD3D12.h", "d3d12/PlatformFunctions.cpp", diff --git a/src/dawn/native/Blob.cpp b/src/dawn/native/Blob.cpp new file mode 100644 index 0000000000..0855735eb1 --- /dev/null +++ b/src/dawn/native/Blob.cpp @@ -0,0 +1,62 @@ +// 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 + +#include "dawn/native/Blob.h" + +namespace dawn::native { + +// static +Blob Blob::Create(size_t size) { + if (size > 0) { + uint8_t* data = new uint8_t[size]; + return Blob(data, size, [=]() { delete[] data; }); + } else { + return Blob(); + } +} + +Blob::Blob() : mData(nullptr), mSize(0), mDeleter({}) {} + +Blob::Blob(uint8_t* data, size_t size, std::function deleter) + : mData(data), mSize(size), mDeleter(std::move(deleter)) {} + +Blob::Blob(Blob&&) = default; + +Blob& Blob::operator=(Blob&&) = default; + +Blob::~Blob() { + if (mDeleter) { + mDeleter(); + } +} + +bool Blob::Empty() const { + return mSize == 0; +} + +const uint8_t* Blob::Data() const { + return mData; +} + +uint8_t* Blob::Data() { + return mData; +} + +size_t Blob::Size() const { + return mSize; +} + +} // namespace dawn::native diff --git a/src/dawn/native/Blob.h b/src/dawn/native/Blob.h new file mode 100644 index 0000000000..396b3f1999 --- /dev/null +++ b/src/dawn/native/Blob.h @@ -0,0 +1,64 @@ +// 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_BLOB_H_ +#define SRC_DAWN_NATIVE_BLOB_H_ + +#include +#include + +#include "dawn/common/Platform.h" + +#if defined(DAWN_PLATFORM_WINDOWS) +#include "dawn/native/d3d12/d3d12_platform.h" +#endif // DAWN_PLATFORM_WINDOWS + +namespace dawn::native { + +// Blob represents a block of bytes. It may be constructed from +// various other container types and uses type erasure to take +// ownership of the container and release its memory on destruction. +class Blob { + public: + static Blob Create(size_t size); + +#if defined(DAWN_PLATFORM_WINDOWS) + static Blob Create(Microsoft::WRL::ComPtr blob); +#endif // DAWN_PLATFORM_WINDOWS + + Blob(); + ~Blob(); + + Blob(const Blob&) = delete; + Blob& operator=(const Blob&) = delete; + + Blob(Blob&&); + Blob& operator=(Blob&&); + + bool Empty() const; + const uint8_t* Data() const; + uint8_t* Data(); + size_t Size() const; + + private: + explicit Blob(uint8_t* data, size_t size, std::function deleter); + + uint8_t* mData; + size_t mSize; + std::function mDeleter; +}; + +} // namespace dawn::native + +#endif // SRC_DAWN_NATIVE_BLOB_H_ diff --git a/src/dawn/native/BlobCache.cpp b/src/dawn/native/BlobCache.cpp index 219fb1e988..f80f479063 100644 --- a/src/dawn/native/BlobCache.cpp +++ b/src/dawn/native/BlobCache.cpp @@ -21,51 +21,10 @@ namespace dawn::native { -// static -CachedBlob CachedBlob::Create(size_t size) { - if (size > 0) { - uint8_t* data = new uint8_t[size]; - return CachedBlob(data, size, [=]() { delete[] data; }); - } else { - return CachedBlob(); - } -} - -CachedBlob::CachedBlob() : mData(nullptr), mSize(0), mDeleter({}) {} - -CachedBlob::CachedBlob(uint8_t* data, size_t size, std::function deleter) - : mData(data), mSize(size), mDeleter(deleter) {} - -CachedBlob::CachedBlob(CachedBlob&&) = default; - -CachedBlob& CachedBlob::operator=(CachedBlob&&) = default; - -CachedBlob::~CachedBlob() { - if (mDeleter) { - mDeleter(); - } -} - -bool CachedBlob::Empty() const { - return mSize == 0; -} - -const uint8_t* CachedBlob::Data() const { - return mData; -} - -uint8_t* CachedBlob::Data() { - return mData; -} - -size_t CachedBlob::Size() const { - return mSize; -} - BlobCache::BlobCache(dawn::platform::CachingInterface* cachingInterface) : mCache(cachingInterface) {} -CachedBlob BlobCache::Load(const CacheKey& key) { +Blob BlobCache::Load(const CacheKey& key) { std::lock_guard lock(mMutex); return LoadInternal(key); } @@ -75,24 +34,24 @@ void BlobCache::Store(const CacheKey& key, size_t valueSize, const void* value) StoreInternal(key, valueSize, value); } -void BlobCache::Store(const CacheKey& key, const CachedBlob& value) { +void BlobCache::Store(const CacheKey& key, const Blob& value) { Store(key, value.Size(), value.Data()); } -CachedBlob BlobCache::LoadInternal(const CacheKey& key) { +Blob BlobCache::LoadInternal(const CacheKey& key) { if (mCache == nullptr) { - return CachedBlob(); + return Blob(); } const size_t expectedSize = mCache->LoadData(key.data(), key.size(), nullptr, 0); if (expectedSize > 0) { // Need to put this inside to trigger copy elision. - CachedBlob result = CachedBlob::Create(expectedSize); + Blob result = Blob::Create(expectedSize); const size_t actualSize = mCache->LoadData(key.data(), key.size(), result.Data(), expectedSize); ASSERT(expectedSize == actualSize); return result; } - return CachedBlob(); + return Blob(); } void BlobCache::StoreInternal(const CacheKey& key, size_t valueSize, const void* value) { diff --git a/src/dawn/native/BlobCache.h b/src/dawn/native/BlobCache.h index d491858bf1..615af2f877 100644 --- a/src/dawn/native/BlobCache.h +++ b/src/dawn/native/BlobCache.h @@ -15,15 +15,10 @@ #ifndef SRC_DAWN_NATIVE_BLOBCACHE_H_ #define SRC_DAWN_NATIVE_BLOBCACHE_H_ -#include -#include #include #include "dawn/common/Platform.h" - -#if defined(DAWN_PLATFORM_WINDOWS) -#include "dawn/native/d3d12/d3d12_platform.h" -#endif // DAWN_PLATFORM_WINDOWS +#include "dawn/native/Blob.h" namespace dawn::platform { class CachingInterface; @@ -31,42 +26,9 @@ class CachingInterface; namespace dawn::native { -class BlobCache; class CacheKey; class InstanceBase; -class CachedBlob { - public: - static CachedBlob Create(size_t size); - -#if defined(DAWN_PLATFORM_WINDOWS) - static CachedBlob Create(Microsoft::WRL::ComPtr blob); -#endif // DAWN_PLATFORM_WINDOWS - - CachedBlob(const CachedBlob&) = delete; - CachedBlob& operator=(const CachedBlob&) = delete; - - CachedBlob(CachedBlob&&); - CachedBlob& operator=(CachedBlob&&); - - ~CachedBlob(); - - bool Empty() const; - const uint8_t* Data() const; - uint8_t* Data(); - size_t Size() const; - void Reset(size_t size); - - CachedBlob(); - - private: - explicit CachedBlob(uint8_t* data, size_t size, std::function deleter); - - uint8_t* mData; - size_t mSize; - std::function mDeleter; -}; - // This class should always be thread-safe because it may be called asynchronously. Its purpose // is to wrap the CachingInterface provided via a platform. class BlobCache { @@ -74,16 +36,16 @@ class BlobCache { explicit BlobCache(dawn::platform::CachingInterface* cachingInterface = nullptr); // Returns empty blob if the key is not found in the cache. - CachedBlob Load(const CacheKey& key); + Blob 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); + void Store(const CacheKey& key, const Blob& 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); + Blob LoadInternal(const CacheKey& key); void StoreInternal(const CacheKey& key, size_t valueSize, const void* value); // Protects thread safety of access to mCache. diff --git a/src/dawn/native/CMakeLists.txt b/src/dawn/native/CMakeLists.txt index 0911e9d1ff..ef774b9d44 100644 --- a/src/dawn/native/CMakeLists.txt +++ b/src/dawn/native/CMakeLists.txt @@ -45,6 +45,8 @@ target_sources(dawn_native PRIVATE "BindGroupTracker.h" "BindingInfo.cpp" "BindingInfo.h" + "Blob.cpp" + "Blob.h" "BlobCache.cpp" "BlobCache.h" "BuddyAllocator.cpp" @@ -241,6 +243,7 @@ if (DAWN_ENABLE_D3D12) "d3d12/BindGroupD3D12.h" "d3d12/BindGroupLayoutD3D12.cpp" "d3d12/BindGroupLayoutD3D12.h" + "d3d12/BlobD3D12.cpp" "d3d12/BufferD3D12.cpp" "d3d12/BufferD3D12.h" "d3d12/CPUDescriptorHeapAllocationD3D12.cpp" @@ -274,7 +277,6 @@ if (DAWN_ENABLE_D3D12) "d3d12/NativeSwapChainImplD3D12.h" "d3d12/PageableD3D12.cpp" "d3d12/PageableD3D12.h" - "d3d12/PipelineCacheD3D12.cpp" "d3d12/PipelineLayoutD3D12.cpp" "d3d12/PipelineLayoutD3D12.h" "d3d12/PlatformFunctions.cpp" diff --git a/src/dawn/native/Device.cpp b/src/dawn/native/Device.cpp index dba1ed0c30..47a9cea277 100644 --- a/src/dawn/native/Device.cpp +++ b/src/dawn/native/Device.cpp @@ -628,15 +628,15 @@ BlobCache* DeviceBase::GetBlobCache() { return nullptr; } -CachedBlob DeviceBase::LoadCachedBlob(const CacheKey& key) { +Blob DeviceBase::LoadCachedBlob(const CacheKey& key) { BlobCache* blobCache = GetBlobCache(); if (!blobCache) { - return CachedBlob(); + return Blob(); } return blobCache->Load(key); } -void DeviceBase::StoreCachedBlob(const CacheKey& key, const CachedBlob& blob) { +void DeviceBase::StoreCachedBlob(const CacheKey& key, const Blob& blob) { if (!blob.Empty()) { BlobCache* blobCache = GetBlobCache(); if (blobCache) { diff --git a/src/dawn/native/Device.h b/src/dawn/native/Device.h index ee791a4e55..349aa7f739 100644 --- a/src/dawn/native/Device.h +++ b/src/dawn/native/Device.h @@ -284,8 +284,8 @@ class DeviceBase : public RefCountedWithExternalCount { MaybeError ValidateIsAlive() const; BlobCache* GetBlobCache(); - CachedBlob LoadCachedBlob(const CacheKey& key); - void StoreCachedBlob(const CacheKey& key, const CachedBlob& blob); + Blob LoadCachedBlob(const CacheKey& key); + void StoreCachedBlob(const CacheKey& key, const Blob& blob); virtual ResultOrError> CreateStagingBuffer(size_t size) = 0; virtual MaybeError CopyFromStagingToBuffer(StagingBufferBase* source, diff --git a/src/dawn/native/PipelineCache.cpp b/src/dawn/native/PipelineCache.cpp index 7cb9081a81..762e08526d 100644 --- a/src/dawn/native/PipelineCache.cpp +++ b/src/dawn/native/PipelineCache.cpp @@ -19,9 +19,9 @@ namespace dawn::native { PipelineCacheBase::PipelineCacheBase(BlobCache* cache, const CacheKey& key) : mCache(cache), mKey(key) {} -CachedBlob PipelineCacheBase::Initialize() { +Blob PipelineCacheBase::Initialize() { ASSERT(!mInitialized); - CachedBlob blob = mCache != nullptr ? mCache->Load(mKey) : CachedBlob(); + Blob blob = mCache != nullptr ? mCache->Load(mKey) : Blob(); mCacheHit = !blob.Empty(); mInitialized = true; return blob; @@ -37,7 +37,7 @@ MaybeError PipelineCacheBase::Flush() { return {}; } // Try to write the data out to the persistent cache. - CachedBlob blob; + Blob blob; DAWN_TRY(SerializeToBlobImpl(&blob)); if (blob.Size() > 0) { // Using a simple heuristic to decide whether to write out the blob right now. May need diff --git a/src/dawn/native/PipelineCache.h b/src/dawn/native/PipelineCache.h index 9b3011e650..5b44a60138 100644 --- a/src/dawn/native/PipelineCache.h +++ b/src/dawn/native/PipelineCache.h @@ -42,13 +42,13 @@ class PipelineCacheBase : public RefCounted { // Initializes and returns the cached blob given the cache and keys. Used by backend // implementations to get the cache and set the cache hit state. Should only be called once. - CachedBlob Initialize(); + Blob Initialize(); private: // Backend implementation of serialization of the cache into a blob. // Note: given that no local cached blob should be destructed and copy elision has strict // requirement cached blob is passed in as a pointer to be assigned. - virtual MaybeError SerializeToBlobImpl(CachedBlob* blob) = 0; + virtual MaybeError SerializeToBlobImpl(Blob* blob) = 0; // The blob cache is owned by the Adapter and pipeline caches are owned/created by devices // or adapters. Since the device owns a reference to the Instance which owns the Adapter, diff --git a/src/dawn/native/d3d12/PipelineCacheD3D12.cpp b/src/dawn/native/d3d12/BlobD3D12.cpp similarity index 65% rename from src/dawn/native/d3d12/PipelineCacheD3D12.cpp rename to src/dawn/native/d3d12/BlobD3D12.cpp index 947f92222c..aa93410319 100644 --- a/src/dawn/native/d3d12/PipelineCacheD3D12.cpp +++ b/src/dawn/native/d3d12/BlobD3D12.cpp @@ -12,22 +12,21 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "dawn/native/BlobCache.h" +#include "dawn/native/Blob.h" #include "dawn/native/d3d12/d3d12_platform.h" namespace dawn::native { // static -CachedBlob CachedBlob::Create(ComPtr blob) { +Blob Blob::Create(ComPtr blob) { // Detach so the deleter callback can "own" the reference ID3DBlob* ptr = blob.Detach(); - return CachedBlob(reinterpret_cast(ptr->GetBufferPointer()), ptr->GetBufferSize(), - [=]() { - // Reattach and drop to delete it. - ComPtr b; - b.Attach(ptr); - b = nullptr; - }); + return Blob(reinterpret_cast(ptr->GetBufferPointer()), ptr->GetBufferSize(), [=]() { + // Reattach and drop to delete it. + ComPtr b; + b.Attach(ptr); + b = nullptr; + }); } } // namespace dawn::native diff --git a/src/dawn/native/d3d12/ComputePipelineD3D12.cpp b/src/dawn/native/d3d12/ComputePipelineD3D12.cpp index 2f34338625..44d10a647a 100644 --- a/src/dawn/native/d3d12/ComputePipelineD3D12.cpp +++ b/src/dawn/native/d3d12/ComputePipelineD3D12.cpp @@ -64,7 +64,7 @@ MaybeError ComputePipeline::Initialize() { mCacheKey.Record(d3dDesc, ToBackend(GetLayout())->GetRootSignatureBlob()); // Try to see if we have anything in the blob cache. - CachedBlob blob = device->LoadCachedBlob(GetCacheKey()); + Blob blob = device->LoadCachedBlob(GetCacheKey()); const bool cacheHit = !blob.Empty(); if (cacheHit) { // Cache hits, attach cached blob to descriptor. @@ -82,7 +82,7 @@ MaybeError ComputePipeline::Initialize() { ComPtr d3dBlob; DAWN_TRY(CheckHRESULT(GetPipelineState()->GetCachedBlob(&d3dBlob), "D3D12 compute pipeline state get cached blob")); - device->StoreCachedBlob(GetCacheKey(), CachedBlob::Create(std::move(d3dBlob))); + device->StoreCachedBlob(GetCacheKey(), Blob::Create(std::move(d3dBlob))); } SetLabelImpl(); diff --git a/src/dawn/native/d3d12/RenderPipelineD3D12.cpp b/src/dawn/native/d3d12/RenderPipelineD3D12.cpp index ce7b347e3a..b6e672d0a1 100644 --- a/src/dawn/native/d3d12/RenderPipelineD3D12.cpp +++ b/src/dawn/native/d3d12/RenderPipelineD3D12.cpp @@ -432,7 +432,7 @@ MaybeError RenderPipeline::Initialize() { mCacheKey.Record(descriptorD3D12, *layout->GetRootSignatureBlob()); // Try to see if we have anything in the blob cache. - CachedBlob blob = device->LoadCachedBlob(GetCacheKey()); + Blob blob = device->LoadCachedBlob(GetCacheKey()); const bool cacheHit = !blob.Empty(); if (cacheHit) { // Cache hits, attach cached blob to descriptor. @@ -449,7 +449,7 @@ MaybeError RenderPipeline::Initialize() { ComPtr d3dBlob; DAWN_TRY(CheckHRESULT(GetPipelineState()->GetCachedBlob(&d3dBlob), "D3D12 render pipeline state get cached blob")); - device->StoreCachedBlob(GetCacheKey(), CachedBlob::Create(std::move(d3dBlob))); + device->StoreCachedBlob(GetCacheKey(), Blob::Create(std::move(d3dBlob))); } SetLabelImpl(); diff --git a/src/dawn/native/vulkan/PipelineCacheVk.cpp b/src/dawn/native/vulkan/PipelineCacheVk.cpp index 2bb1039466..6eab53c53f 100644 --- a/src/dawn/native/vulkan/PipelineCacheVk.cpp +++ b/src/dawn/native/vulkan/PipelineCacheVk.cpp @@ -50,7 +50,7 @@ VkPipelineCache PipelineCache::GetHandle() const { return mHandle; } -MaybeError PipelineCache::SerializeToBlobImpl(CachedBlob* blob) { +MaybeError PipelineCache::SerializeToBlobImpl(Blob* blob) { if (mHandle == VK_NULL_HANDLE) { // Pipeline cache isn't created successfully return {}; @@ -62,7 +62,7 @@ MaybeError PipelineCache::SerializeToBlobImpl(CachedBlob* blob) { device->fn.GetPipelineCacheData(device->GetVkDevice(), mHandle, &bufferSize, nullptr), "GetPipelineCacheData")); if (bufferSize > 0) { - *blob = CachedBlob::Create(bufferSize); + *blob = Blob::Create(bufferSize); DAWN_TRY(CheckVkSuccess(device->fn.GetPipelineCacheData(device->GetVkDevice(), mHandle, &bufferSize, blob->Data()), "GetPipelineCacheData")); @@ -71,7 +71,7 @@ MaybeError PipelineCache::SerializeToBlobImpl(CachedBlob* blob) { } void PipelineCache::Initialize() { - CachedBlob blob = PipelineCacheBase::Initialize(); + Blob blob = PipelineCacheBase::Initialize(); VkPipelineCacheCreateInfo createInfo; createInfo.flags = 0; diff --git a/src/dawn/native/vulkan/PipelineCacheVk.h b/src/dawn/native/vulkan/PipelineCacheVk.h index 85a889171e..605991f3b7 100644 --- a/src/dawn/native/vulkan/PipelineCacheVk.h +++ b/src/dawn/native/vulkan/PipelineCacheVk.h @@ -38,7 +38,7 @@ class PipelineCache final : public PipelineCacheBase { ~PipelineCache() override; void Initialize(); - MaybeError SerializeToBlobImpl(CachedBlob* blob) override; + MaybeError SerializeToBlobImpl(Blob* blob) override; DeviceBase* mDevice; VkPipelineCache mHandle = VK_NULL_HANDLE;