From c813d270a19ca1e15a504d46983f4d8ac6805ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Sat, 27 Aug 2022 15:50:41 +0200 Subject: Fix use after moved and reduce memory footprint of passes & subpasses --- source/blender/draw/intern/draw_command.cc | 8 ++--- source/blender/draw/intern/draw_command.hh | 16 ++++----- source/blender/draw/intern/draw_pass.hh | 54 ++++++++++++++++++++++++++---- 3 files changed, 59 insertions(+), 19 deletions(-) diff --git a/source/blender/draw/intern/draw_command.cc b/source/blender/draw/intern/draw_command.cc index 17f09db78f2..2cdf12ad06b 100644 --- a/source/blender/draw/intern/draw_command.cc +++ b/source/blender/draw/intern/draw_command.cc @@ -471,8 +471,8 @@ std::string StencilSet::serialize() const * \{ */ void DrawCommandBuf::bind(RecordingState &state, - Vector
&headers, - Vector &commands, + Vector &headers, + Vector &commands, VisibilityBuf &visibility_buf) { UNUSED_VARS(headers, commands, visibility_buf); @@ -521,8 +521,8 @@ void DrawCommandBuf::bind(RecordingState &state, } void DrawMultiBuf::bind(RecordingState &state, - Vector
&headers, - Vector &commands, + Vector &headers, + Vector &commands, VisibilityBuf &visibility_buf) { UNUSED_VARS(headers, commands); diff --git a/source/blender/draw/intern/draw_command.hh b/source/blender/draw/intern/draw_command.hh index b368a463828..54830805706 100644 --- a/source/blender/draw/intern/draw_command.hh +++ b/source/blender/draw/intern/draw_command.hh @@ -369,8 +369,8 @@ class DrawCommandBuf { public: void clear(){}; - void append_draw(Vector
&headers, - Vector &commands, + void append_draw(Vector &headers, + Vector &commands, GPUBatch *batch, uint instance_len, uint vertex_len, @@ -386,8 +386,8 @@ class DrawCommandBuf { } void bind(RecordingState &state, - Vector
&headers, - Vector &commands, + Vector &headers, + Vector &commands, VisibilityBuf &visibility_buf); }; @@ -468,8 +468,8 @@ class DrawMultiBuf { group_ids_.clear(); } - void append_draw(Vector
&headers, - Vector &commands, + void append_draw(Vector &headers, + Vector &commands, GPUBatch *batch, uint instance_len, uint vertex_len, @@ -526,8 +526,8 @@ class DrawMultiBuf { } void bind(RecordingState &state, - Vector
&headers, - Vector &commands, + Vector &headers, + Vector &commands, VisibilityBuf &visibility_buf); }; diff --git a/source/blender/draw/intern/draw_pass.hh b/source/blender/draw/intern/draw_pass.hh index 197961ac4e0..a183c223492 100644 --- a/source/blender/draw/intern/draw_pass.hh +++ b/source/blender/draw/intern/draw_pass.hh @@ -60,6 +60,42 @@ class Manager; namespace detail { +/** + * Special container that never moves allocated items and has fast indexing. + */ +template +class SubPassVector { + private: + Vector, 0> blocks_; + + public: + void clear() + { + blocks_.clear(); + } + + int64_t append_and_get_index(T &&elem) + { + /* Do not go over the inline size so that existing members never move. */ + if (blocks_.size() == 0 || blocks_.last().size() == block_size) { + blocks_.append({}); + } + return blocks_.last().append_and_get_index(elem) + (blocks_.size() - 1) * block_size; + } + + T &operator[](int64_t index) + { + return blocks_[index / block_size][index % block_size]; + } + + const T &operator[](int64_t index) const + { + return blocks_[index / block_size][index % block_size]; + } +}; + /** * Public API of a draw pass. */ @@ -71,13 +107,13 @@ class PassBase { protected: /** Highest level of the command stream. Split command stream in different command types. */ - Vector headers_; + Vector headers_; /** Commands referenced by headers (which contains their types). */ - Vector commands_; + Vector commands_; /* Reference to draw commands buffer. Either own or from parent pass. */ DrawCommandBufType &draw_commands_buf_; /* Reference to sub-pass commands buffer. Either own or from parent pass. */ - Vector, 0> &sub_passes_; + SubPassVector> &sub_passes_; /** Currently bound shader. Used for interface queries. */ GPUShader *shader_; @@ -86,7 +122,7 @@ class PassBase { PassBase(const char *name, DrawCommandBufType &draw_command_buf, - Vector, 0> &sub_passes, + SubPassVector> &sub_passes, GPUShader *shader = nullptr) : draw_commands_buf_(draw_command_buf), sub_passes_(sub_passes), @@ -289,7 +325,7 @@ template class Pass : public detail::PassBase, 0> sub_passes_main_; + SubPassVector> sub_passes_main_; /** Draws are recorded as indirect draws for compatibility with the multi-draw pipeline. */ DrawCommandBufType draw_commands_buf_main_; @@ -716,12 +752,16 @@ template inline void PassBase::bind(int slot, GPUUniformBuf *buffer) template inline void PassBase::bind(int slot, GPUTexture *texture, eGPUSamplerState state) { - create_command(Type::ResourceBind).resource_bind = {slot, texture, state}; + if (slot != -1) { + create_command(Type::ResourceBind).resource_bind = {slot, texture, state}; + } } template inline void PassBase::bind(int slot, draw::Image *image) { - create_command(Type::ResourceBind).resource_bind = {slot, image}; + if (slot != -1) { + create_command(Type::ResourceBind).resource_bind = {slot, image}; + } } template inline void PassBase::bind(const char *name, GPUStorageBuf **buffer) -- cgit v1.2.3