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

View File

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