diff options
Diffstat (limited to 'source/blender/draw/intern/DRW_gpu_wrapper.hh')
-rw-r--r-- | source/blender/draw/intern/DRW_gpu_wrapper.hh | 111 |
1 files changed, 88 insertions, 23 deletions
diff --git a/source/blender/draw/intern/DRW_gpu_wrapper.hh b/source/blender/draw/intern/DRW_gpu_wrapper.hh index d7e752a43f4..257f01a5562 100644 --- a/source/blender/draw/intern/DRW_gpu_wrapper.hh +++ b/source/blender/draw/intern/DRW_gpu_wrapper.hh @@ -102,7 +102,7 @@ class DataBuffer { { BLI_STATIC_ASSERT(!device_only, ""); BLI_assert(index >= 0); - BLI_assert(index < len); + BLI_assert(index < len_); return data_[index]; } @@ -110,7 +110,7 @@ class DataBuffer { { BLI_STATIC_ASSERT(!device_only, ""); BLI_assert(index >= 0); - BLI_assert(index < len); + BLI_assert(index < len_); return data_[index]; } @@ -139,7 +139,7 @@ class DataBuffer { const T *end() const { BLI_STATIC_ASSERT(!device_only, ""); - return data_ + len; + return data_ + len_; } T *begin() @@ -150,13 +150,13 @@ class DataBuffer { T *end() { BLI_STATIC_ASSERT(!device_only, ""); - return data_ + len; + return data_ + len_; } operator Span<T>() const { BLI_STATIC_ASSERT(!device_only, ""); - return Span<T>(data_, len); + return Span<T>(data_, len_); } }; @@ -217,7 +217,9 @@ class StorageCommon : public DataBuffer<T, len, false>, NonMovable, NonCopyable if (name) { name_ = name; } - init(len); + this->len_ = len; + constexpr GPUUsageType usage = device_only ? GPU_USAGE_DEVICE_ONLY : GPU_USAGE_DYNAMIC; + ssbo_ = GPU_storagebuf_create_ex(sizeof(T) * this->len_, nullptr, usage, this->name_); } ~StorageCommon() @@ -225,15 +227,6 @@ class StorageCommon : public DataBuffer<T, len, false>, NonMovable, NonCopyable GPU_storagebuf_free(ssbo_); } - void resize(int64_t new_size) - { - BLI_assert(new_size > 0); - if (new_size != this->len_) { - GPU_storagebuf_free(ssbo_); - this->init(new_size); - } - } - void push_update(void) { BLI_assert(device_only == false); @@ -249,14 +242,6 @@ class StorageCommon : public DataBuffer<T, len, false>, NonMovable, NonCopyable { return &ssbo_; } - - private: - void init(int64_t new_size) - { - this->len_ = new_size; - GPUUsageType usage = device_only ? GPU_USAGE_DEVICE_ONLY : GPU_USAGE_DYNAMIC; - ssbo_ = GPU_storagebuf_create_ex(sizeof(T) * this->len_, nullptr, usage, this->name_); - } }; } // namespace detail @@ -333,6 +318,34 @@ class StorageArrayBuffer : public detail::StorageCommon<T, len, device_only> { { MEM_freeN(this->data_); } + + void resize(int64_t new_size) + { + BLI_assert(new_size > 0); + if (new_size != this->len_) { + /* Manual realloc since MEM_reallocN_aligned does not exists. */ + T *new_data_ = (T *)MEM_mallocN_aligned(new_size * sizeof(T), 16, this->name_); + memcpy(new_data_, this->data_, min_uu(this->len_, new_size) * sizeof(T)); + MEM_freeN(this->data_); + this->data_ = new_data_; + GPU_storagebuf_free(this->ssbo_); + + this->len_ = new_size; + constexpr GPUUsageType usage = device_only ? GPU_USAGE_DEVICE_ONLY : GPU_USAGE_DYNAMIC; + this->ssbo_ = GPU_storagebuf_create_ex(sizeof(T) * this->len_, nullptr, usage, this->name_); + } + } + + /* Resize on access. */ + T &get_or_resize(int64_t index) + { + BLI_assert(index >= 0); + if (index >= this->len_) { + size_t size = power_of_2_max_u(index + 1); + this->resize(size); + } + return this->data_[index]; + } }; template< @@ -880,4 +893,56 @@ class Framebuffer : NonCopyable { /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Double & Triple buffering util + * + * This is not strictly related to a GPU type and could be moved elsewhere. + * \{ */ + +template<typename T, int64_t len> class SwapChain { + private: + std::array<T, len> chain_; + int64_t index_ = 0; + + public: + void swap() + { + index_ = (index_ + 1) % len; + } + + T ¤t() + { + return chain_[index_]; + } + + T &previous() + { + /* Avoid modulo operation with negative numbers. */ + return chain_[(index_ + len - 1) % len]; + } + + T &next() + { + return chain_[(index_ + 1) % len]; + } + + const T ¤t() const + { + return chain_[index_]; + } + + const T &previous() const + { + /* Avoid modulo operation with negative numbers. */ + return chain_[(index_ + len - 1) % len]; + } + + const T &next() const + { + return chain_[(index_ + 1) % len]; + } +}; + +/** \} */ + } // namespace blender::draw |