From 79230bf2134d16de920d1ed3f23b26869bcdacd2 Mon Sep 17 00:00:00 2001 From: Austin Eng Date: Fri, 13 Mar 2020 23:10:00 +0000 Subject: [PATCH] Slab-allocate frontend Vulkan bind groups Bug: dawn:340 Change-Id: I3ef0b8a0585fac93ffb77d4642d13c14afbae177 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/16745 Commit-Queue: Austin Eng Reviewed-by: Kai Ninomiya --- src/dawn_native/vulkan/BindGroupLayoutVk.cpp | 28 +++++++++++++++++--- src/dawn_native/vulkan/BindGroupLayoutVk.h | 15 ++++++++--- src/dawn_native/vulkan/BindGroupVk.cpp | 23 +++++++--------- src/dawn_native/vulkan/BindGroupVk.h | 14 +++++----- 4 files changed, 54 insertions(+), 26 deletions(-) diff --git a/src/dawn_native/vulkan/BindGroupLayoutVk.cpp b/src/dawn_native/vulkan/BindGroupLayoutVk.cpp index 90c8366272..606c59f65f 100644 --- a/src/dawn_native/vulkan/BindGroupLayoutVk.cpp +++ b/src/dawn_native/vulkan/BindGroupLayoutVk.cpp @@ -15,6 +15,7 @@ #include "dawn_native/vulkan/BindGroupLayoutVk.h" #include "common/BitSetIterator.h" +#include "dawn_native/vulkan/BindGroupVk.h" #include "dawn_native/vulkan/DescriptorSetService.h" #include "dawn_native/vulkan/DeviceVk.h" #include "dawn_native/vulkan/FencedDeleter.h" @@ -127,6 +128,12 @@ namespace dawn_native { namespace vulkan { return {}; } + BindGroupLayout::BindGroupLayout(DeviceBase* device, + const BindGroupLayoutDescriptor* descriptor) + : BindGroupLayoutBase(device, descriptor), + mBindGroupAllocator(MakeFrontendBindGroupAllocator(4096)) { + } + BindGroupLayout::~BindGroupLayout() { Device* device = ToBackend(GetDevice()); @@ -148,7 +155,19 @@ namespace dawn_native { namespace vulkan { return mHandle; } - ResultOrError BindGroupLayout::AllocateOneSet() { + ResultOrError BindGroupLayout::AllocateBindGroup( + Device* device, + const BindGroupDescriptor* descriptor) { + DescriptorSetAllocation descriptorSetAllocation; + DAWN_TRY_ASSIGN(descriptorSetAllocation, AllocateOneDescriptorSet()); + return mBindGroupAllocator.Allocate(device, descriptor, descriptorSetAllocation); + } + + void BindGroupLayout::DeallocateBindGroup(BindGroup* bindGroup) { + mBindGroupAllocator.Deallocate(bindGroup); + } + + ResultOrError BindGroupLayout::AllocateOneDescriptorSet() { Device* device = ToBackend(GetDevice()); // Reuse a previous allocation if available. @@ -198,16 +217,17 @@ namespace dawn_native { namespace vulkan { return {{mAllocations.size() - 1, descriptorSet}}; } - void BindGroupLayout::Deallocate(DescriptorSetAllocation* allocation) { + void BindGroupLayout::DeallocateDescriptorSet( + DescriptorSetAllocation* descriptorSetAllocation) { // We can't reuse the descriptor set right away because the Vulkan spec says in the // documentation for vkCmdBindDescriptorSets that the set may be consumed any time between // host execution of the command and the end of the draw/dispatch. ToBackend(GetDevice()) ->GetDescriptorSetService() - ->AddDeferredDeallocation(this, allocation->index); + ->AddDeferredDeallocation(this, descriptorSetAllocation->index); // Clear the content of allocation so that use after frees are more visible. - *allocation = {}; + *descriptorSetAllocation = {}; } void BindGroupLayout::FinishDeallocation(size_t index) { diff --git a/src/dawn_native/vulkan/BindGroupLayoutVk.h b/src/dawn_native/vulkan/BindGroupLayoutVk.h index 947f29d656..47d8abef57 100644 --- a/src/dawn_native/vulkan/BindGroupLayoutVk.h +++ b/src/dawn_native/vulkan/BindGroupLayoutVk.h @@ -17,12 +17,14 @@ #include "dawn_native/BindGroupLayout.h" +#include "common/SlabAllocator.h" #include "common/vulkan_platform.h" #include namespace dawn_native { namespace vulkan { + class BindGroup; class Device; VkDescriptorType VulkanDescriptorType(wgpu::BindingType type, bool isDynamic); @@ -49,18 +51,23 @@ namespace dawn_native { namespace vulkan { public: static ResultOrError Create(Device* device, const BindGroupLayoutDescriptor* descriptor); + + BindGroupLayout(DeviceBase* device, const BindGroupLayoutDescriptor* descriptor); ~BindGroupLayout(); VkDescriptorSetLayout GetHandle() const; - ResultOrError AllocateOneSet(); - void Deallocate(DescriptorSetAllocation* allocation); + ResultOrError AllocateBindGroup(Device* device, + const BindGroupDescriptor* descriptor); + void DeallocateBindGroup(BindGroup* bindGroup); + + ResultOrError AllocateOneDescriptorSet(); + void DeallocateDescriptorSet(DescriptorSetAllocation* descriptorSetAllocation); // Interaction with the DescriptorSetService. void FinishDeallocation(size_t index); private: - using BindGroupLayoutBase::BindGroupLayoutBase; MaybeError Initialize(); std::vector mPoolSizes; @@ -74,6 +81,8 @@ namespace dawn_native { namespace vulkan { std::vector mAvailableAllocations; VkDescriptorSetLayout mHandle = VK_NULL_HANDLE; + + SlabAllocator mBindGroupAllocator; }; }} // namespace dawn_native::vulkan diff --git a/src/dawn_native/vulkan/BindGroupVk.cpp b/src/dawn_native/vulkan/BindGroupVk.cpp index f633d6b94d..164c53795a 100644 --- a/src/dawn_native/vulkan/BindGroupVk.cpp +++ b/src/dawn_native/vulkan/BindGroupVk.cpp @@ -28,16 +28,14 @@ namespace dawn_native { namespace vulkan { // static ResultOrError BindGroup::Create(Device* device, const BindGroupDescriptor* descriptor) { - std::unique_ptr group = std::make_unique(device, descriptor); - DAWN_TRY(group->Initialize()); - return group.release(); + return ToBackend(descriptor->layout)->AllocateBindGroup(device, descriptor); } - MaybeError BindGroup::Initialize() { - Device* device = ToBackend(GetDevice()); - - DAWN_TRY_ASSIGN(mAllocation, ToBackend(GetLayout())->AllocateOneSet()); - + BindGroup::BindGroup(Device* device, + const BindGroupDescriptor* descriptor, + DescriptorSetAllocation descriptorSetAllocation) + : BindGroupBase(this, device, descriptor), + mDescriptorSetAllocation(descriptorSetAllocation) { // Now do a write of a single descriptor set with all possible chained data allocated on the // stack. uint32_t numWrites = 0; @@ -50,7 +48,7 @@ namespace dawn_native { namespace vulkan { auto& write = writes[numWrites]; write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; write.pNext = nullptr; - write.dstSet = mAllocation.set; + write.dstSet = GetHandle(); write.dstBinding = bindingIndex; write.dstArrayElement = 0; write.descriptorCount = 1; @@ -97,16 +95,15 @@ namespace dawn_native { namespace vulkan { // TODO(cwallez@chromium.org): Batch these updates device->fn.UpdateDescriptorSets(device->GetVkDevice(), numWrites, writes.data(), 0, nullptr); - - return {}; } BindGroup::~BindGroup() { - ToBackend(GetLayout())->Deallocate(&mAllocation); + ToBackend(GetLayout())->DeallocateDescriptorSet(&mDescriptorSetAllocation); + ToBackend(GetLayout())->DeallocateBindGroup(this); } VkDescriptorSet BindGroup::GetHandle() const { - return mAllocation.set; + return mDescriptorSetAllocation.set; } }} // namespace dawn_native::vulkan diff --git a/src/dawn_native/vulkan/BindGroupVk.h b/src/dawn_native/vulkan/BindGroupVk.h index 727f959656..c912fe2ef2 100644 --- a/src/dawn_native/vulkan/BindGroupVk.h +++ b/src/dawn_native/vulkan/BindGroupVk.h @@ -17,6 +17,7 @@ #include "dawn_native/BindGroup.h" +#include "common/PlacementAllocated.h" #include "common/vulkan_platform.h" #include "dawn_native/vulkan/BindGroupLayoutVk.h" @@ -24,21 +25,22 @@ namespace dawn_native { namespace vulkan { class Device; - class BindGroup : public BindGroupBaseOwnBindingData { + class BindGroup : public BindGroupBase, public PlacementAllocated { public: static ResultOrError Create(Device* device, const BindGroupDescriptor* descriptor); - ~BindGroup(); + + BindGroup(Device* device, + const BindGroupDescriptor* descriptor, + DescriptorSetAllocation descriptorSetAllocation); + ~BindGroup() override; VkDescriptorSet GetHandle() const; private: - using BindGroupBaseOwnBindingData::BindGroupBaseOwnBindingData; - MaybeError Initialize(); - // The descriptor set in this allocation outlives the BindGroup because it is owned by // the BindGroupLayout which is referenced by the BindGroup. - DescriptorSetAllocation mAllocation; + DescriptorSetAllocation mDescriptorSetAllocation; }; }} // namespace dawn_native::vulkan