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-27 16:50:41 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-08-27 16:50:41 +0300
commitc813d270a19ca1e15a504d46983f4d8ac6805ce9 (patch)
treef90a12e12f1ebbd403459abd10ad65532ea86375
parentb6117386b9683ecebd810fdc1e574e79b91f3894 (diff)
Fix use after moved and reduce memory footprint of passes & subpasses
-rw-r--r--source/blender/draw/intern/draw_command.cc8
-rw-r--r--source/blender/draw/intern/draw_command.hh16
-rw-r--r--source/blender/draw/intern/draw_pass.hh54
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<Header> &headers,
- Vector<Undetermined> &commands,
+ Vector<Header, 0> &headers,
+ Vector<Undetermined, 0> &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<Header> &headers,
- Vector<Undetermined> &commands,
+ Vector<Header, 0> &headers,
+ Vector<Undetermined, 0> &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<Header> &headers,
- Vector<Undetermined> &commands,
+ void append_draw(Vector<Header, 0> &headers,
+ Vector<Undetermined, 0> &commands,
GPUBatch *batch,
uint instance_len,
uint vertex_len,
@@ -386,8 +386,8 @@ class DrawCommandBuf {
}
void bind(RecordingState &state,
- Vector<Header> &headers,
- Vector<Undetermined> &commands,
+ Vector<Header, 0> &headers,
+ Vector<Undetermined, 0> &commands,
VisibilityBuf &visibility_buf);
};
@@ -468,8 +468,8 @@ class DrawMultiBuf {
group_ids_.clear();
}
- void append_draw(Vector<Header> &headers,
- Vector<Undetermined> &commands,
+ void append_draw(Vector<Header, 0> &headers,
+ Vector<Undetermined, 0> &commands,
GPUBatch *batch,
uint instance_len,
uint vertex_len,
@@ -526,8 +526,8 @@ class DrawMultiBuf {
}
void bind(RecordingState &state,
- Vector<Header> &headers,
- Vector<Undetermined> &commands,
+ Vector<Header, 0> &headers,
+ Vector<Undetermined, 0> &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
@@ -61,6 +61,42 @@ class Manager;
namespace detail {
/**
+ * Special container that never moves allocated items and has fast indexing.
+ */
+template<typename T,
+ /** Numbers of element of type T to allocate together. */
+ int64_t block_size = 16>
+class SubPassVector {
+ private:
+ Vector<Vector<T, block_size>, 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.
*/
template<
@@ -71,13 +107,13 @@ class PassBase {
protected:
/** Highest level of the command stream. Split command stream in different command types. */
- Vector<command::Header> headers_;
+ Vector<command::Header, 0> headers_;
/** Commands referenced by headers (which contains their types). */
- Vector<command::Undetermined> commands_;
+ Vector<command::Undetermined, 0> 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<PassBase<DrawCommandBufType>, 0> &sub_passes_;
+ SubPassVector<PassBase<DrawCommandBufType>> &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<PassBase<DrawCommandBufType>, 0> &sub_passes,
+ SubPassVector<PassBase<DrawCommandBufType>> &sub_passes,
GPUShader *shader = nullptr)
: draw_commands_buf_(draw_command_buf),
sub_passes_(sub_passes),
@@ -289,7 +325,7 @@ template<typename DrawCommandBufType> class Pass : public detail::PassBase<DrawC
private:
/** Sub-passes referenced by headers. */
- Vector<detail::PassBase<DrawCommandBufType>, 0> sub_passes_main_;
+ SubPassVector<detail::PassBase<DrawCommandBufType>> 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<class T> inline void PassBase<T>::bind(int slot, GPUUniformBuf *buffer)
template<class T>
inline void PassBase<T>::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<class T> inline void PassBase<T>::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<class T> inline void PassBase<T>::bind(const char *name, GPUStorageBuf **buffer)