diff options
-rw-r--r-- | source/blender/draw/intern/draw_debug.cc | 8 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_exec.c | 2 | ||||
-rw-r--r-- | source/blender/gpu/GPU_batch.h | 4 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_batch.cc | 14 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_batch_private.hh | 6 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_batch.cc | 34 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_batch.hh | 6 |
7 files changed, 61 insertions, 13 deletions
diff --git a/source/blender/draw/intern/draw_debug.cc b/source/blender/draw/intern/draw_debug.cc index b9d10302c1e..ab78db5d913 100644 --- a/source/blender/draw/intern/draw_debug.cc +++ b/source/blender/draw/intern/draw_debug.cc @@ -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(); diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 4dda0ceb2ef..0e39cc1d3b9 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -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) diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h index b79560fdd1e..8f524f72fa1 100644 --- a/source/blender/gpu/GPU_batch.h +++ b/source/blender/gpu/GPU_batch.h @@ -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 */ diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc index 13a91d2c808..9092ad5110c 100644 --- a/source/blender/gpu/intern/gpu_batch.cc +++ b/source/blender/gpu/intern/gpu_batch.cc @@ -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); } /** \} */ diff --git a/source/blender/gpu/intern/gpu_batch_private.hh b/source/blender/gpu/intern/gpu_batch_private.hh index 8ca19884fd7..59646925d68 100644 --- a/source/blender/gpu/intern/gpu_batch_private.hh +++ b/source/blender/gpu/intern/gpu_batch_private.hh @@ -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 diff --git a/source/blender/gpu/opengl/gl_batch.cc b/source/blender/gpu/opengl/gl_batch.cc index 4ec86b98cbe..ff8867fe3e6 100644 --- a/source/blender/gpu/opengl/gl_batch.cc +++ b/source/blender/gpu/opengl/gl_batch.cc @@ -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); diff --git a/source/blender/gpu/opengl/gl_batch.hh b/source/blender/gpu/opengl/gl_batch.hh index 0d7ea7c4a9e..714aa1220be 100644 --- a/source/blender/gpu/opengl/gl_batch.hh +++ b/source/blender/gpu/opengl/gl_batch.hh @@ -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. */ |