Fixup circular buffers for full rotation

This commit is contained in:
Dr. Chat 2016-05-23 09:58:46 -05:00
parent c6e905db2f
commit 6e21d88250
1 changed files with 10 additions and 32 deletions

View File

@ -103,23 +103,22 @@ bool CircularBuffer::CanAcquire(VkDeviceSize length) {
length = xe::round_up(length, alignment_); length = xe::round_up(length, alignment_);
if (allocations_.empty()) { if (allocations_.empty()) {
// Read head has caught up to write head (entire buffer available for write) // Read head has caught up to write head (entire buffer available for write)
assert(read_head_ == write_head_); return capacity_ >= length;
return capacity_ > length;
} else if (write_head_ < read_head_) { } else if (write_head_ < read_head_) {
// Write head wrapped around and is behind read head. // Write head wrapped around and is behind read head.
// | write |---- read ----| // | write |---- read ----|
return (read_head_ - write_head_) > length; return (read_head_ - write_head_) >= length;
} else { } else if (write_head_ > read_head_) {
// Read head behind write head. // Read head behind write head.
// 1. Check if there's enough room from write -> capacity // 1. Check if there's enough room from write -> capacity
// | |---- read ----| write | // | |---- read ----| write |
if ((capacity_ - write_head_) > length) { if ((capacity_ - write_head_) >= length) {
return true; return true;
} }
// 2. Check if there's enough room from 0 -> read // 2. Check if there's enough room from 0 -> read
// | write |---- read ----| | // | write |---- read ----| |
if ((read_head_) > length) { if ((read_head_ - 0) >= length) {
return true; return true;
} }
} }
@ -129,29 +128,13 @@ bool CircularBuffer::CanAcquire(VkDeviceSize length) {
CircularBuffer::Allocation* CircularBuffer::Acquire( CircularBuffer::Allocation* CircularBuffer::Acquire(
VkDeviceSize length, std::shared_ptr<Fence> fence) { VkDeviceSize length, std::shared_ptr<Fence> fence) {
if (!CanAcquire(length)) { VkDeviceSize aligned_length = xe::round_up(length, alignment_);
if (!CanAcquire(aligned_length)) {
return nullptr; return nullptr;
} }
VkDeviceSize aligned_length = xe::round_up(length, alignment_);
assert_true(write_head_ % alignment_ == 0); assert_true(write_head_ % alignment_ == 0);
if (allocations_.empty()) { if (write_head_ < read_head_) {
// Entire buffer available.
assert(read_head_ == write_head_);
assert(capacity_ > aligned_length);
write_head_ = aligned_length;
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;
allocations_.push_back(alloc);
return alloc;
} else if (write_head_ < read_head_) {
// 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);
@ -167,7 +150,7 @@ CircularBuffer::Allocation* CircularBuffer::Acquire(
return alloc; return alloc;
} else { } else {
// Write head 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(); auto alloc = new Allocation();
@ -181,7 +164,7 @@ CircularBuffer::Allocation* CircularBuffer::Acquire(
allocations_.push_back(alloc); allocations_.push_back(alloc);
return alloc; return alloc;
} else if ((read_head_ - 0) > aligned_length) { } else if ((read_head_ - 0) >= aligned_length) {
// Free space from begin -> read // Free space from begin -> read
auto alloc = new Allocation(); auto alloc = new Allocation();
alloc->host_ptr = host_base_ + write_head_; alloc->host_ptr = host_base_ + write_head_;
@ -236,11 +219,6 @@ void CircularBuffer::Scavenge() {
delete *it; delete *it;
it = allocations_.erase(it); it = allocations_.erase(it);
} }
if (allocations_.empty()) {
// Reset R/W heads.
read_head_ = write_head_ = 0;
}
} }
} // namespace vulkan } // namespace vulkan