diff --git a/src/dawn_native/Device.cpp b/src/dawn_native/Device.cpp index 1c30cd509c..b0ef00db13 100644 --- a/src/dawn_native/Device.cpp +++ b/src/dawn_native/Device.cpp @@ -169,6 +169,8 @@ namespace dawn_native { mDynamicUploader = nullptr; mMapRequestTracker = nullptr; + mEmptyBindGroupLayout = nullptr; + AssumeCommandsComplete(); // Tell the backend that it can free all the objects now that the GPU timeline is empty. ShutDownImpl(); @@ -411,6 +413,24 @@ namespace dawn_native { ASSERT(removedCount == 1); } + ResultOrError DeviceBase::GetOrCreateEmptyBindGroupLayout() { + if (!mEmptyBindGroupLayout) { + BindGroupLayoutDescriptor desc = {}; + desc.entryCount = 0; + desc.entries = nullptr; + + BindGroupLayoutBase* bgl = nullptr; + if (ConsumedError(GetOrCreateBindGroupLayout(&desc), &bgl)) { + return BindGroupLayoutBase::MakeError(this); + } + mEmptyBindGroupLayout = bgl; + return bgl; + } else { + mEmptyBindGroupLayout->Reference(); + return mEmptyBindGroupLayout.Get(); + } + } + ResultOrError DeviceBase::GetOrCreateComputePipeline( const ComputePipelineDescriptor* descriptor) { ComputePipelineBase blueprint(this, descriptor); diff --git a/src/dawn_native/Device.h b/src/dawn_native/Device.h index 94d916f7c2..f9a3b43aba 100644 --- a/src/dawn_native/Device.h +++ b/src/dawn_native/Device.h @@ -112,6 +112,8 @@ namespace dawn_native { const BindGroupLayoutDescriptor* descriptor); void UncacheBindGroupLayout(BindGroupLayoutBase* obj); + ResultOrError GetOrCreateEmptyBindGroupLayout(); + ResultOrError GetOrCreateComputePipeline( const ComputePipelineDescriptor* descriptor); void UncacheComputePipeline(ComputePipelineBase* obj); @@ -340,6 +342,8 @@ namespace dawn_native { struct Caches; std::unique_ptr mCaches; + Ref mEmptyBindGroupLayout; + std::unique_ptr mDynamicUploader; std::unique_ptr mErrorScopeTracker; std::unique_ptr mFenceSignalTracker; diff --git a/src/dawn_native/Pipeline.cpp b/src/dawn_native/Pipeline.cpp index df344416a5..15dd06838d 100644 --- a/src/dawn_native/Pipeline.cpp +++ b/src/dawn_native/Pipeline.cpp @@ -91,19 +91,10 @@ namespace dawn_native { } BindGroupIndex groupIndex(groupIndexIn); - if (!mLayout->GetBindGroupLayoutsMask()[groupIndex]) { - // Get or create an empty bind group layout. - // TODO(enga): Consider caching this object on the Device and reusing it. - // Today, this can't be done correctly because of the order of Device destruction. - // For example, vulkan::~Device will be called before ~DeviceBase. If DeviceBase owns - // a Ref, then the VkDevice will be destroyed before the - // VkDescriptorSetLayout. - BindGroupLayoutDescriptor desc = {}; - desc.entryCount = 0; - desc.entries = nullptr; + if (!mLayout->GetBindGroupLayoutsMask()[groupIndex]) { BindGroupLayoutBase* bgl = nullptr; - if (GetDevice()->ConsumedError(GetDevice()->GetOrCreateBindGroupLayout(&desc), &bgl)) { + if (GetDevice()->ConsumedError(GetDevice()->GetOrCreateEmptyBindGroupLayout(), &bgl)) { return BindGroupLayoutBase::MakeError(GetDevice()); } return bgl;