Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2022-08-23 15:11:45 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-08-23 15:11:45 +0300
commit53eea778d738661a7680de7261d745bb111f65e1 (patch)
tree63bc46f00a27fc1d133e5c4088dc6f43ae7b249c
parent46dc57af82e629b854ad4af12ccb3e43ea509b0e (diff)
GPUBatch: Implement multidrawindirect and indirect offset
-rw-r--r--source/blender/draw/intern/draw_debug.cc8
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c2
-rw-r--r--source/blender/gpu/GPU_batch.h4
-rw-r--r--source/blender/gpu/intern/gpu_batch.cc14
-rw-r--r--source/blender/gpu/intern/gpu_batch_private.hh6
-rw-r--r--source/blender/gpu/opengl/gl_batch.cc34
-rw-r--r--source/blender/gpu/opengl/gl_batch.hh6
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 c085b592a77..867d2b5e1bd 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -180,7 +180,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 0b47a7b2952..897f21e8b54 100644
--- a/source/blender/gpu/intern/gpu_batch.cc
+++ b/source/blender/gpu/intern/gpu_batch.cc
@@ -270,13 +270,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. */