diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2022-10-26 14:02:21 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2022-10-30 14:36:33 +0300 |
commit | 117e17fb2259c60c4d744ae364004177de244b6e (patch) | |
tree | f72291075b3d3077ea1e8525b06f4616f2b5ef45 | |
parent | 9bd38750b39637f5b52ac64944af5b6113c30c03 (diff) |
DRW: Manager: Allow custom draw command in PassMain
This allows using drawcalls with non default vertex range.
These calls will be culled like any other instance by the GPU culling
pipeline. But they will not be batched together since the vertex range
is part of the group.
-rw-r--r-- | source/blender/draw/intern/draw_command.hh | 26 | ||||
-rw-r--r-- | source/blender/draw/tests/draw_pass_test.cc | 7 |
2 files changed, 22 insertions, 11 deletions
diff --git a/source/blender/draw/intern/draw_command.hh b/source/blender/draw/intern/draw_command.hh index 5307a242e39..145ec0fe231 100644 --- a/source/blender/draw/intern/draw_command.hh +++ b/source/blender/draw/intern/draw_command.hh @@ -473,10 +473,8 @@ class DrawMultiBuf { uint vertex_first, ResourceHandle handle) { - /* Unsupported for now. Use PassSimple. */ - BLI_assert(vertex_first == 0 || vertex_first == -1); - BLI_assert(vertex_len == -1); - UNUSED_VARS_NDEBUG(vertex_len, vertex_first); + /* Custom draw-calls cannot be batched and will produce one group per draw. */ + const bool custom_group = (vertex_first != 0 || vertex_first != -1 || vertex_len != -1); instance_len = instance_len != -1 ? instance_len : 1; @@ -493,8 +491,14 @@ class DrawMultiBuf { bool inverted = handle.has_inverted_handedness(); - if (group_id == uint(-1)) { + DrawPrototype &draw = prototype_buf_.get_or_resize(prototype_count_++); + draw.resource_handle = handle.raw; + draw.instance_len = instance_len; + draw.group_id = group_id; + + if (group_id == uint(-1) || custom_group) { uint new_group_id = group_count_++; + draw.group_id = new_group_id; DrawGroup &group = group_buf_.get_or_resize(new_group_id); group.next = cmd.group_first; @@ -503,11 +507,16 @@ class DrawMultiBuf { group.gpu_batch = batch; group.front_proto_len = 0; group.back_proto_len = 0; + group.vertex_len = vertex_len; + group.vertex_first = vertex_first; + /* Custom group are not to be registered in the group_ids_. */ + if (!custom_group) { + group_id = new_group_id; + } /* For serialization only. */ (inverted ? group.back_proto_len : group.front_proto_len)++; /* Append to list. */ cmd.group_first = new_group_id; - group_id = new_group_id; } else { DrawGroup &group = group_buf_[group_id]; @@ -516,11 +525,6 @@ class DrawMultiBuf { /* For serialization only. */ (inverted ? group.back_proto_len : group.front_proto_len)++; } - - DrawPrototype &draw = prototype_buf_.get_or_resize(prototype_count_++); - draw.group_id = group_id; - draw.resource_handle = handle.raw; - draw.instance_len = instance_len; } void bind(RecordingState &state, diff --git a/source/blender/draw/tests/draw_pass_test.cc b/source/blender/draw/tests/draw_pass_test.cc index 394ca8bd3cf..95ab8fa2ef1 100644 --- a/source/blender/draw/tests/draw_pass_test.cc +++ b/source/blender/draw/tests/draw_pass_test.cc @@ -181,12 +181,19 @@ static void test_draw_pass_multi_draw() pass.draw_procedural(GPU_PRIM_LINES, 1, -1, -1, {5}); pass.draw_procedural(GPU_PRIM_POINTS, 6, -1, -1, {5}); pass.draw_procedural(GPU_PRIM_TRIS, 3, -1, -1, {6}); + /* Custom calls should use their own group and never be batched. */ + pass.draw_procedural(GPU_PRIM_TRIS, 2, 2, 2, {7}); + pass.draw_procedural(GPU_PRIM_TRIS, 2, 2, 2, {8}); std::string result = pass.serialize(); std::stringstream expected; expected << ".test.multi_draw" << std::endl; expected << " .shader_bind(gpu_shader_3D_image_color)" << std::endl; expected << " .draw_multi(3)" << std::endl; + expected << " .group(id=4, len=2)" << std::endl; + expected << " .proto(instance_len=2, resource_id=8, front_face)" << std::endl; + expected << " .group(id=3, len=2)" << std::endl; + expected << " .proto(instance_len=2, resource_id=7, front_face)" << std::endl; expected << " .group(id=2, len=1)" << std::endl; expected << " .proto(instance_len=1, resource_id=5, front_face)" << std::endl; expected << " .group(id=1, len=15)" << std::endl; |