DescriptorPool fenced pool

This commit is contained in:
Dr. Chat 2017-01-28 14:03:21 -06:00
parent 90b0541d72
commit a16dc261da
2 changed files with 62 additions and 13 deletions

View File

@ -92,7 +92,11 @@ DescriptorPool::DescriptorPool(VkDevice device, uint32_t max_count,
&descriptor_pool_); &descriptor_pool_);
CheckResult(err, "vkCreateDescriptorPool"); CheckResult(err, "vkCreateDescriptorPool");
} }
DescriptorPool::~DescriptorPool() {} DescriptorPool::~DescriptorPool() {
FreeAllEntries();
vkDestroyDescriptorPool(device_, descriptor_pool_, nullptr);
descriptor_pool_ = nullptr;
}
VkDescriptorSet DescriptorPool::AllocateEntry(void* data) { VkDescriptorSet DescriptorPool::AllocateEntry(void* data) {
VkDescriptorSetLayout layout = reinterpret_cast<VkDescriptorSetLayout>(data); VkDescriptorSetLayout layout = reinterpret_cast<VkDescriptorSetLayout>(data);

View File

@ -49,6 +49,7 @@ class BaseFencedPool {
void Scavenge() { void Scavenge() {
while (pending_batch_list_head_) { while (pending_batch_list_head_) {
auto batch = pending_batch_list_head_; auto batch = pending_batch_list_head_;
assert_not_null(batch->fence);
if (vkGetFenceStatus(device_, batch->fence) == VK_SUCCESS) { if (vkGetFenceStatus(device_, batch->fence) == VK_SUCCESS) {
// Batch has completed. Reclaim. // Batch has completed. Reclaim.
pending_batch_list_head_ = batch->next; pending_batch_list_head_ = batch->next;
@ -71,8 +72,10 @@ class BaseFencedPool {
// Begins a new batch. // Begins a new batch.
// All entries acquired within this batch will be marked as in-use until // All entries acquired within this batch will be marked as in-use until
// the fence specified in EndBatch is signalled. // the fence returned is signalled.
VkFence BeginBatch() { // Pass in a fence to use an external fence. This assumes the fence has been
// reset.
VkFence BeginBatch(VkFence fence = nullptr) {
assert_null(open_batch_); assert_null(open_batch_);
Batch* batch = nullptr; Batch* batch = nullptr;
if (free_batch_list_head_) { if (free_batch_list_head_) {
@ -80,19 +83,49 @@ class BaseFencedPool {
batch = free_batch_list_head_; batch = free_batch_list_head_;
free_batch_list_head_ = batch->next; free_batch_list_head_ = batch->next;
batch->next = nullptr; batch->next = nullptr;
vkResetFences(device_, 1, &batch->fence);
if (batch->flags & kBatchOwnsFence && !fence) {
// Reset owned fence.
vkResetFences(device_, 1, &batch->fence);
} else if ((batch->flags & kBatchOwnsFence) && fence) {
// Transfer owned -> external
vkDestroyFence(device_, batch->fence, nullptr);
batch->fence = fence;
} else if (!(batch->flags & kBatchOwnsFence) && !fence) {
// external -> owned
VkFenceCreateInfo info;
info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
info.pNext = nullptr;
info.flags = 0;
VkResult res = vkCreateFence(device_, &info, nullptr, &batch->fence);
if (res != VK_SUCCESS) {
assert_always();
}
batch->flags |= kBatchOwnsFence;
} else {
// external -> external
batch->fence = fence;
}
} else { } else {
// Allocate new batch. // Allocate new batch.
batch = new Batch(); batch = new Batch();
batch->next = nullptr; batch->next = nullptr;
batch->flags = 0;
VkFenceCreateInfo info; if (!fence) {
info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; VkFenceCreateInfo info;
info.pNext = nullptr; info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
info.flags = 0; info.pNext = nullptr;
VkResult res = vkCreateFence(device_, &info, nullptr, &batch->fence); info.flags = 0;
if (res != VK_SUCCESS) { VkResult res = vkCreateFence(device_, &info, nullptr, &batch->fence);
assert_always(); if (res != VK_SUCCESS) {
assert_always();
}
batch->flags |= kBatchOwnsFence;
} else {
batch->fence = fence;
} }
} }
batch->entry_list_head = nullptr; batch->entry_list_head = nullptr;
@ -203,6 +236,11 @@ class BaseFencedPool {
while (free_batch_list_head_) { while (free_batch_list_head_) {
auto batch = free_batch_list_head_; auto batch = free_batch_list_head_;
free_batch_list_head_ = batch->next; free_batch_list_head_ = batch->next;
if (batch->flags & kBatchOwnsFence) {
vkDestroyFence(device_, batch->fence, nullptr);
batch->fence = nullptr;
}
delete batch; delete batch;
} }
while (free_entry_list_head_) { while (free_entry_list_head_) {
@ -225,9 +263,12 @@ class BaseFencedPool {
Batch* next; Batch* next;
Entry* entry_list_head; Entry* entry_list_head;
Entry* entry_list_tail; Entry* entry_list_tail;
uint32_t flags;
VkFence fence; VkFence fence;
}; };
static const uint32_t kBatchOwnsFence = 1;
Batch* free_batch_list_head_ = nullptr; Batch* free_batch_list_head_ = nullptr;
Entry* free_entry_list_head_ = nullptr; Entry* free_entry_list_head_ = nullptr;
Batch* pending_batch_list_head_ = nullptr; Batch* pending_batch_list_head_ = nullptr;
@ -257,14 +298,18 @@ class CommandBufferPool
class DescriptorPool : public BaseFencedPool<DescriptorPool, VkDescriptorSet> { class DescriptorPool : public BaseFencedPool<DescriptorPool, VkDescriptorSet> {
public: public:
typedef BaseFencedPool<DescriptorPool, VkDescriptorSet> Base;
DescriptorPool(VkDevice device, uint32_t max_count, DescriptorPool(VkDevice device, uint32_t max_count,
std::vector<VkDescriptorPoolSize> pool_sizes); std::vector<VkDescriptorPoolSize> pool_sizes);
~DescriptorPool() override; ~DescriptorPool() override;
VkDescriptorSet AcquireEntry(VkDescriptorSetLayout layout) { return nullptr; } VkDescriptorSet AcquireEntry(VkDescriptorSetLayout layout) {
return Base::AcquireEntry(layout);
}
protected: protected:
friend class BaseFencedPool<DescriptorPool, VkCommandBuffer>; friend class BaseFencedPool<DescriptorPool, VkDescriptorSet>;
VkDescriptorSet AllocateEntry(void* data); VkDescriptorSet AllocateEntry(void* data);
void FreeEntry(VkDescriptorSet handle); void FreeEntry(VkDescriptorSet handle);