Batch flushing buffer.
This commit is contained in:
parent
bb15d2f62f
commit
5236477043
|
@ -24,6 +24,8 @@ CircularBuffer::CircularBuffer(size_t capacity, size_t alignment)
|
||||||
: capacity_(capacity),
|
: capacity_(capacity),
|
||||||
alignment_(alignment),
|
alignment_(alignment),
|
||||||
write_head_(0),
|
write_head_(0),
|
||||||
|
dirty_start_(UINT64_MAX),
|
||||||
|
dirty_end_(0),
|
||||||
buffer_(0),
|
buffer_(0),
|
||||||
gpu_base_(0),
|
gpu_base_(0),
|
||||||
host_base_(nullptr) {}
|
host_base_(nullptr) {}
|
||||||
|
@ -63,12 +65,15 @@ void CircularBuffer::Shutdown() {
|
||||||
buffer_ = 0;
|
buffer_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CircularBuffer::CanAcquire(size_t length) {
|
||||||
|
size_t aligned_length = poly::round_up(length, alignment_);
|
||||||
|
return write_head_ + aligned_length <= capacity_;
|
||||||
|
}
|
||||||
|
|
||||||
CircularBuffer::Allocation CircularBuffer::Acquire(size_t length) {
|
CircularBuffer::Allocation CircularBuffer::Acquire(size_t length) {
|
||||||
// Addresses must always be % 256.
|
// Addresses must always be % 256.
|
||||||
size_t aligned_length = poly::round_up(length, alignment_);
|
size_t aligned_length = poly::round_up(length, alignment_);
|
||||||
|
|
||||||
assert_true(aligned_length <= capacity_, "Request too large");
|
assert_true(aligned_length <= capacity_, "Request too large");
|
||||||
|
|
||||||
if (write_head_ + aligned_length > capacity_) {
|
if (write_head_ + aligned_length > capacity_) {
|
||||||
// Flush and wait.
|
// Flush and wait.
|
||||||
WaitUntilClean();
|
WaitUntilClean();
|
||||||
|
@ -79,16 +84,30 @@ CircularBuffer::Allocation CircularBuffer::Acquire(size_t length) {
|
||||||
allocation.gpu_ptr = gpu_base_ + write_head_;
|
allocation.gpu_ptr = gpu_base_ + write_head_;
|
||||||
allocation.offset = write_head_;
|
allocation.offset = write_head_;
|
||||||
allocation.length = length;
|
allocation.length = length;
|
||||||
|
allocation.aligned_length = aligned_length;
|
||||||
write_head_ += aligned_length;
|
write_head_ += aligned_length;
|
||||||
return allocation;
|
return allocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CircularBuffer::Commit(Allocation allocation) {
|
void CircularBuffer::Commit(Allocation allocation) {
|
||||||
glFlushMappedNamedBufferRange(buffer_, allocation.gpu_ptr - gpu_base_,
|
uintptr_t start = allocation.gpu_ptr - gpu_base_;
|
||||||
allocation.length);
|
uintptr_t end = start + allocation.aligned_length;
|
||||||
|
dirty_start_ = std::min(dirty_start_, start);
|
||||||
|
dirty_end_ = std::max(dirty_end_, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CircularBuffer::Flush() {
|
||||||
|
if (dirty_start_ == dirty_end_ || dirty_start_ == UINT64_MAX) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glFlushMappedNamedBufferRange(buffer_, dirty_start_,
|
||||||
|
dirty_end_ - dirty_start_);
|
||||||
|
dirty_start_ = UINT64_MAX;
|
||||||
|
dirty_end_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CircularBuffer::WaitUntilClean() {
|
void CircularBuffer::WaitUntilClean() {
|
||||||
|
Flush();
|
||||||
glFinish();
|
glFinish();
|
||||||
write_head_ = 0;
|
write_head_ = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ class CircularBuffer {
|
||||||
GLuint64 gpu_ptr;
|
GLuint64 gpu_ptr;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
size_t length;
|
size_t length;
|
||||||
|
size_t aligned_length;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
|
@ -35,8 +36,10 @@ class CircularBuffer {
|
||||||
|
|
||||||
GLuint handle() const { return buffer_; }
|
GLuint handle() const { return buffer_; }
|
||||||
|
|
||||||
|
bool CanAcquire(size_t length);
|
||||||
Allocation Acquire(size_t length);
|
Allocation Acquire(size_t length);
|
||||||
void Commit(Allocation allocation);
|
void Commit(Allocation allocation);
|
||||||
|
void Flush();
|
||||||
|
|
||||||
void WaitUntilClean();
|
void WaitUntilClean();
|
||||||
|
|
||||||
|
@ -44,6 +47,8 @@ class CircularBuffer {
|
||||||
size_t capacity_;
|
size_t capacity_;
|
||||||
size_t alignment_;
|
size_t alignment_;
|
||||||
uintptr_t write_head_;
|
uintptr_t write_head_;
|
||||||
|
uintptr_t dirty_start_;
|
||||||
|
uintptr_t dirty_end_;
|
||||||
GLuint buffer_;
|
GLuint buffer_;
|
||||||
GLuint64 gpu_base_;
|
GLuint64 gpu_base_;
|
||||||
uint8_t* host_base_;
|
uint8_t* host_base_;
|
||||||
|
|
|
@ -1428,6 +1428,7 @@ bool CommandProcessor::IssueDraw(DrawCommand* draw_command) {
|
||||||
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, scratch_buffer_.handle(),
|
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, scratch_buffer_.handle(),
|
||||||
allocation.offset, allocation.length);
|
allocation.offset, allocation.length);
|
||||||
scratch_buffer_.Commit(std::move(allocation));
|
scratch_buffer_.Commit(std::move(allocation));
|
||||||
|
scratch_buffer_.Flush();
|
||||||
|
|
||||||
if (cmd.index_buffer.address) {
|
if (cmd.index_buffer.address) {
|
||||||
// Indexed draw.
|
// Indexed draw.
|
||||||
|
|
|
@ -382,7 +382,11 @@ GL4ProfilerDisplay::Vertex* GL4ProfilerDisplay::BeginVertices(size_t count) {
|
||||||
if (draw_command_count_ + 1 > kMaxCommands) {
|
if (draw_command_count_ + 1 > kMaxCommands) {
|
||||||
Flush();
|
Flush();
|
||||||
}
|
}
|
||||||
current_allocation_ = vertex_buffer_.Acquire(sizeof(Vertex) * count);
|
size_t total_length = sizeof(Vertex) * count;
|
||||||
|
if (!vertex_buffer_.CanAcquire(total_length)) {
|
||||||
|
Flush();
|
||||||
|
}
|
||||||
|
current_allocation_ = vertex_buffer_.Acquire(total_length);
|
||||||
return reinterpret_cast<Vertex*>(current_allocation_.host_ptr);
|
return reinterpret_cast<Vertex*>(current_allocation_.host_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,12 +412,14 @@ void GL4ProfilerDisplay::Flush() {
|
||||||
if (!draw_command_count_) {
|
if (!draw_command_count_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
vertex_buffer_.Flush();
|
||||||
for (size_t i = 0; i < draw_command_count_; ++i) {
|
for (size_t i = 0; i < draw_command_count_; ++i) {
|
||||||
glDrawArrays(draw_commands_[i].prim_type,
|
glDrawArrays(draw_commands_[i].prim_type,
|
||||||
GLint(draw_commands_[i].vertex_offset),
|
GLint(draw_commands_[i].vertex_offset),
|
||||||
GLsizei(draw_commands_[i].vertex_count));
|
GLsizei(draw_commands_[i].vertex_count));
|
||||||
}
|
}
|
||||||
draw_command_count_ = 0;
|
draw_command_count_ = 0;
|
||||||
|
// TODO(benvanik): don't finish here.
|
||||||
vertex_buffer_.WaitUntilClean();
|
vertex_buffer_.WaitUntilClean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue