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 <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
Austin Eng 2020-03-13 23:10:00 +00:00 committed by Commit Bot service account
parent 459c2f930f
commit 79230bf213
4 changed files with 54 additions and 26 deletions

View File

@ -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<BindGroup>(4096)) {
}
BindGroupLayout::~BindGroupLayout() {
Device* device = ToBackend(GetDevice());
@ -148,7 +155,19 @@ namespace dawn_native { namespace vulkan {
return mHandle;
}
ResultOrError<DescriptorSetAllocation> BindGroupLayout::AllocateOneSet() {
ResultOrError<BindGroup*> 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<DescriptorSetAllocation> 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) {

View File

@ -17,12 +17,14 @@
#include "dawn_native/BindGroupLayout.h"
#include "common/SlabAllocator.h"
#include "common/vulkan_platform.h"
#include <vector>
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<BindGroupLayout*> Create(Device* device,
const BindGroupLayoutDescriptor* descriptor);
BindGroupLayout(DeviceBase* device, const BindGroupLayoutDescriptor* descriptor);
~BindGroupLayout();
VkDescriptorSetLayout GetHandle() const;
ResultOrError<DescriptorSetAllocation> AllocateOneSet();
void Deallocate(DescriptorSetAllocation* allocation);
ResultOrError<BindGroup*> AllocateBindGroup(Device* device,
const BindGroupDescriptor* descriptor);
void DeallocateBindGroup(BindGroup* bindGroup);
ResultOrError<DescriptorSetAllocation> AllocateOneDescriptorSet();
void DeallocateDescriptorSet(DescriptorSetAllocation* descriptorSetAllocation);
// Interaction with the DescriptorSetService.
void FinishDeallocation(size_t index);
private:
using BindGroupLayoutBase::BindGroupLayoutBase;
MaybeError Initialize();
std::vector<VkDescriptorPoolSize> mPoolSizes;
@ -74,6 +81,8 @@ namespace dawn_native { namespace vulkan {
std::vector<size_t> mAvailableAllocations;
VkDescriptorSetLayout mHandle = VK_NULL_HANDLE;
SlabAllocator<BindGroup> mBindGroupAllocator;
};
}} // namespace dawn_native::vulkan

View File

@ -28,16 +28,14 @@ namespace dawn_native { namespace vulkan {
// static
ResultOrError<BindGroup*> BindGroup::Create(Device* device,
const BindGroupDescriptor* descriptor) {
std::unique_ptr<BindGroup> group = std::make_unique<BindGroup>(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

View File

@ -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<BindGroup*> 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