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:
Diffstat (limited to 'source/blender/draw/intern/DRW_gpu_wrapper.hh')
-rw-r--r--source/blender/draw/intern/DRW_gpu_wrapper.hh111
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 &current()
+ {
+ 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 &current() 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