[Vulkan UI] Use an underlying queue instead of a list of pointers in CircularBuffer

This commit is contained in:
DrChat 2018-03-02 22:01:55 -06:00
parent 2e3115660f
commit 82e8781549
2 changed files with 37 additions and 42 deletions

View File

@ -177,46 +177,46 @@ CircularBuffer::Allocation* CircularBuffer::Acquire(VkDeviceSize length,
// Write head behind read head.
assert_true(read_head_ - write_head_ >= aligned_length);
auto alloc = new Allocation();
alloc->host_ptr = host_base_ + write_head_;
alloc->gpu_memory = gpu_memory_;
alloc->offset = gpu_base_ + write_head_;
alloc->length = length;
alloc->aligned_length = aligned_length;
alloc->fence = fence;
Allocation alloc;
alloc.host_ptr = host_base_ + write_head_;
alloc.gpu_memory = gpu_memory_;
alloc.offset = gpu_base_ + write_head_;
alloc.length = length;
alloc.aligned_length = aligned_length;
alloc.fence = fence;
write_head_ += aligned_length;
allocations_.push_back(alloc);
allocations_.push(alloc);
return alloc;
return &allocations_.back();
} else {
// Write head equal to/after read head
if (capacity_ - write_head_ >= aligned_length) {
// Free space from write -> capacity
auto alloc = new Allocation();
alloc->host_ptr = host_base_ + write_head_;
alloc->gpu_memory = gpu_memory_;
alloc->offset = gpu_base_ + write_head_;
alloc->length = length;
alloc->aligned_length = aligned_length;
alloc->fence = fence;
Allocation alloc;
alloc.host_ptr = host_base_ + write_head_;
alloc.gpu_memory = gpu_memory_;
alloc.offset = gpu_base_ + write_head_;
alloc.length = length;
alloc.aligned_length = aligned_length;
alloc.fence = fence;
write_head_ += aligned_length;
allocations_.push_back(alloc);
allocations_.push(alloc);
return alloc;
return &allocations_.back();
} else if ((read_head_ - 0) >= aligned_length) {
// Not enough space from write -> capacity, but there is enough free space
// from begin -> read
auto alloc = new Allocation();
alloc->host_ptr = host_base_ + 0;
alloc->gpu_memory = gpu_memory_;
alloc->offset = gpu_base_ + 0;
alloc->length = length;
alloc->aligned_length = aligned_length;
alloc->fence = fence;
Allocation alloc;
alloc.host_ptr = host_base_ + 0;
alloc.gpu_memory = gpu_memory_;
alloc.offset = gpu_base_ + 0;
alloc.length = length;
alloc.aligned_length = aligned_length;
alloc.fence = fence;
write_head_ = aligned_length;
allocations_.push_back(alloc);
allocations_.push(alloc);
return alloc;
return &allocations_.back();
}
}
@ -244,30 +244,25 @@ void CircularBuffer::Flush(VkDeviceSize offset, VkDeviceSize length) {
}
void CircularBuffer::Clear() {
for (auto alloc : allocations_) {
delete alloc;
}
allocations_.clear();
std::swap(allocations_, std::queue<Allocation>());
write_head_ = read_head_ = 0;
}
void CircularBuffer::Scavenge() {
for (auto it = allocations_.begin(); it != allocations_.end();) {
if (vkGetFenceStatus(*device_, (*it)->fence) != VK_SUCCESS) {
while (!allocations_.empty()) {
Allocation& alloc = allocations_.front();
if (vkGetFenceStatus(*device_, alloc.fence) != VK_SUCCESS) {
// Don't bother freeing following allocations to ensure proper ordering.
break;
}
if (capacity_ - read_head_ < (*it)->aligned_length) {
allocations_.pop();
if (capacity_ - read_head_ < alloc.aligned_length) {
// This allocation is stored at the beginning of the buffer.
read_head_ = (*it)->aligned_length;
read_head_ = alloc.aligned_length;
} else {
read_head_ += (*it)->aligned_length;
read_head_ += alloc.aligned_length;
}
delete *it;
it = allocations_.erase(it);
}
if (allocations_.empty()) {

View File

@ -10,7 +10,7 @@
#ifndef XENIA_UI_VULKAN_CIRCULAR_BUFFER_H_
#define XENIA_UI_VULKAN_CIRCULAR_BUFFER_H_
#include <list>
#include <queue>
#include "xenia/ui/vulkan/vulkan.h"
#include "xenia/ui/vulkan/vulkan_device.h"
@ -83,7 +83,7 @@ class CircularBuffer {
VkDeviceSize gpu_base_ = 0;
uint8_t* host_base_ = nullptr;
std::list<Allocation*> allocations_;
std::queue<Allocation> allocations_;
};
} // namespace vulkan