GPUBatch: Add multi_draw_indirect capability and indirect buffer offset
This is for completion and to be used by the new draw manager.
This commit is contained in:
@@ -525,14 +525,14 @@ void DebugDraw::display_lines()
|
||||
if (gpu_draw_buf_used) {
|
||||
GPU_debug_group_begin("GPU");
|
||||
GPU_storagebuf_bind(gpu_draw_buf_, slot);
|
||||
GPU_batch_draw_indirect(batch, gpu_draw_buf_);
|
||||
GPU_batch_draw_indirect(batch, gpu_draw_buf_, 0);
|
||||
GPU_storagebuf_unbind(gpu_draw_buf_);
|
||||
GPU_debug_group_end();
|
||||
}
|
||||
|
||||
GPU_debug_group_begin("CPU");
|
||||
GPU_storagebuf_bind(cpu_draw_buf_, slot);
|
||||
GPU_batch_draw_indirect(batch, cpu_draw_buf_);
|
||||
GPU_batch_draw_indirect(batch, cpu_draw_buf_, 0);
|
||||
GPU_storagebuf_unbind(cpu_draw_buf_);
|
||||
GPU_debug_group_end();
|
||||
|
||||
@@ -557,14 +557,14 @@ void DebugDraw::display_prints()
|
||||
if (gpu_print_buf_used) {
|
||||
GPU_debug_group_begin("GPU");
|
||||
GPU_storagebuf_bind(gpu_print_buf_, slot);
|
||||
GPU_batch_draw_indirect(batch, gpu_print_buf_);
|
||||
GPU_batch_draw_indirect(batch, gpu_print_buf_, 0);
|
||||
GPU_storagebuf_unbind(gpu_print_buf_);
|
||||
GPU_debug_group_end();
|
||||
}
|
||||
|
||||
GPU_debug_group_begin("CPU");
|
||||
GPU_storagebuf_bind(cpu_print_buf_, slot);
|
||||
GPU_batch_draw_indirect(batch, cpu_print_buf_);
|
||||
GPU_batch_draw_indirect(batch, cpu_print_buf_, 0);
|
||||
GPU_storagebuf_unbind(cpu_print_buf_);
|
||||
GPU_debug_group_end();
|
||||
|
||||
|
||||
@@ -891,7 +891,7 @@ static void draw_call_indirect(DRWShadingGroup *shgroup,
|
||||
}
|
||||
|
||||
GPU_batch_set_shader(batch, shgroup->shader);
|
||||
GPU_batch_draw_indirect(batch, indirect_buf);
|
||||
GPU_batch_draw_indirect(batch, indirect_buf, 0);
|
||||
}
|
||||
|
||||
static void draw_call_batching_start(DRWCommandsState *state)
|
||||
|
||||
@@ -187,7 +187,9 @@ void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_fi
|
||||
* Issue a draw call using GPU computed arguments. The argument are expected to be valid for the
|
||||
* type of geometry drawn (index or non-indexed).
|
||||
*/
|
||||
void GPU_batch_draw_indirect(GPUBatch *batch, GPUStorageBuf *indirect_buf);
|
||||
void GPU_batch_draw_indirect(GPUBatch *batch, GPUStorageBuf *indirect_buf, intptr_t offset);
|
||||
void GPU_batch_multi_draw_indirect(
|
||||
GPUBatch *batch, GPUStorageBuf *indirect_buf, int count, intptr_t offset, intptr_t stride);
|
||||
|
||||
#if 0 /* future plans */
|
||||
|
||||
|
||||
@@ -294,13 +294,23 @@ void GPU_batch_draw_advanced(
|
||||
batch->draw(v_first, v_count, i_first, i_count);
|
||||
}
|
||||
|
||||
void GPU_batch_draw_indirect(GPUBatch *gpu_batch, GPUStorageBuf *indirect_buf)
|
||||
void GPU_batch_draw_indirect(GPUBatch *gpu_batch, GPUStorageBuf *indirect_buf, intptr_t offset)
|
||||
{
|
||||
BLI_assert(Context::get()->shader != nullptr);
|
||||
BLI_assert(indirect_buf != nullptr);
|
||||
Batch *batch = static_cast<Batch *>(gpu_batch);
|
||||
|
||||
batch->draw_indirect(indirect_buf);
|
||||
batch->draw_indirect(indirect_buf, offset);
|
||||
}
|
||||
|
||||
void GPU_batch_multi_draw_indirect(
|
||||
GPUBatch *gpu_batch, GPUStorageBuf *indirect_buf, int count, intptr_t offset, intptr_t stride)
|
||||
{
|
||||
BLI_assert(Context::get()->shader != nullptr);
|
||||
BLI_assert(indirect_buf != nullptr);
|
||||
Batch *batch = static_cast<Batch *>(gpu_batch);
|
||||
|
||||
batch->multi_draw_indirect(indirect_buf, count, offset, stride);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -29,7 +29,11 @@ class Batch : public GPUBatch {
|
||||
virtual ~Batch() = default;
|
||||
|
||||
virtual void draw(int v_first, int v_count, int i_first, int i_count) = 0;
|
||||
virtual void draw_indirect(GPUStorageBuf *indirect_buf) = 0;
|
||||
virtual void draw_indirect(GPUStorageBuf *indirect_buf, intptr_t offset) = 0;
|
||||
virtual void multi_draw_indirect(GPUStorageBuf *indirect_buf,
|
||||
int count,
|
||||
intptr_t offset,
|
||||
intptr_t stride) = 0;
|
||||
|
||||
/* Convenience casts. */
|
||||
IndexBuf *elem_() const
|
||||
|
||||
@@ -327,12 +327,13 @@ void GLBatch::draw(int v_first, int v_count, int i_first, int i_count)
|
||||
}
|
||||
}
|
||||
|
||||
void GLBatch::draw_indirect(GPUStorageBuf *indirect_buf)
|
||||
void GLBatch::draw_indirect(GPUStorageBuf *indirect_buf, intptr_t offset)
|
||||
{
|
||||
GL_CHECK_RESOURCES("Batch");
|
||||
|
||||
this->bind(0);
|
||||
|
||||
/* TODO(fclem): Make the barrier and binding optional if consecutive draws are issued. */
|
||||
dynamic_cast<GLStorageBuf *>(unwrap(indirect_buf))->bind_as(GL_DRAW_INDIRECT_BUFFER);
|
||||
/* This barrier needs to be here as it only work on the currently bound indirect buffer. */
|
||||
glMemoryBarrier(GL_COMMAND_BARRIER_BIT);
|
||||
@@ -341,10 +342,37 @@ void GLBatch::draw_indirect(GPUStorageBuf *indirect_buf)
|
||||
if (elem) {
|
||||
const GLIndexBuf *el = this->elem_();
|
||||
GLenum index_type = to_gl(el->index_type_);
|
||||
glDrawElementsIndirect(gl_type, index_type, (GLvoid *)nullptr);
|
||||
glDrawElementsIndirect(gl_type, index_type, (GLvoid *)offset);
|
||||
}
|
||||
else {
|
||||
glDrawArraysIndirect(gl_type, (GLvoid *)nullptr);
|
||||
glDrawArraysIndirect(gl_type, (GLvoid *)offset);
|
||||
}
|
||||
/* Unbind. */
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
|
||||
}
|
||||
|
||||
void GLBatch::multi_draw_indirect(GPUStorageBuf *indirect_buf,
|
||||
int count,
|
||||
intptr_t offset,
|
||||
intptr_t stride)
|
||||
{
|
||||
GL_CHECK_RESOURCES("Batch");
|
||||
|
||||
this->bind(0);
|
||||
|
||||
/* TODO(fclem): Make the barrier and binding optional if consecutive draws are issued. */
|
||||
dynamic_cast<GLStorageBuf *>(unwrap(indirect_buf))->bind_as(GL_DRAW_INDIRECT_BUFFER);
|
||||
/* This barrier needs to be here as it only work on the currently bound indirect buffer. */
|
||||
glMemoryBarrier(GL_COMMAND_BARRIER_BIT);
|
||||
|
||||
GLenum gl_type = to_gl(prim_type);
|
||||
if (elem) {
|
||||
const GLIndexBuf *el = this->elem_();
|
||||
GLenum index_type = to_gl(el->index_type_);
|
||||
glMultiDrawElementsIndirect(gl_type, index_type, (GLvoid *)offset, count, stride);
|
||||
}
|
||||
else {
|
||||
glMultiDrawArraysIndirect(gl_type, (GLvoid *)offset, count, stride);
|
||||
}
|
||||
/* Unbind. */
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
|
||||
|
||||
@@ -91,7 +91,11 @@ class GLBatch : public Batch {
|
||||
|
||||
public:
|
||||
void draw(int v_first, int v_count, int i_first, int i_count) override;
|
||||
void draw_indirect(GPUStorageBuf *indirect_buf) override;
|
||||
void draw_indirect(GPUStorageBuf *indirect_buf, intptr_t offset) override;
|
||||
void multi_draw_indirect(GPUStorageBuf *indirect_buf,
|
||||
int count,
|
||||
intptr_t offset,
|
||||
intptr_t stride) override;
|
||||
void bind(int i_first);
|
||||
|
||||
/* Convenience getters. */
|
||||
|
||||
Reference in New Issue
Block a user