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>2020-09-06 03:46:51 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-09-06 23:13:06 +0300
commit4ea93029c65fd4cdb8b707494855120c0f792952 (patch)
treea02801daaaf0f0a4e1bb7be84d34e27759b32a36 /source/blender/gpu/intern/gpu_index_buffer.cc
parent84d67bd0a937e842618ee7843958f3147ba6af58 (diff)
GPUIndexBuf: GL backend Isolation
This is part of the Vulkan backend task T68990. There is no real change, only making some code re-organisation. This also make the IndexBuf completely abstract from outside the GPU module.
Diffstat (limited to 'source/blender/gpu/intern/gpu_index_buffer.cc')
-rw-r--r--source/blender/gpu/intern/gpu_index_buffer.cc248
1 files changed, 105 insertions, 143 deletions
diff --git a/source/blender/gpu/intern/gpu_index_buffer.cc b/source/blender/gpu/intern/gpu_index_buffer.cc
index 832c5dc76b2..5448e6efbe4 100644
--- a/source/blender/gpu/intern/gpu_index_buffer.cc
+++ b/source/blender/gpu/intern/gpu_index_buffer.cc
@@ -25,55 +25,22 @@
#include "MEM_guardedalloc.h"
-#include "GPU_glew.h"
-#include "GPU_index_buffer.h"
+#include "BLI_utildefines.h"
-#include "gpu_context_private.hh"
+#include "gpu_backend.hh"
-#include <stdlib.h>
+#include "gpu_index_buffer_private.hh"
#define KEEP_SINGLE_COPY 1
#define RESTART_INDEX 0xFFFFFFFF
-static GLenum convert_index_type_to_gl(GPUIndexBufType type)
-{
-#if GPU_TRACK_INDEX_RANGE
- return (type == GPU_INDEX_U32) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
-#else
- return GL_UNSIGNED_INT;
-#endif
-}
-
-uint GPU_indexbuf_size_get(const GPUIndexBuf *elem)
-{
-#if GPU_TRACK_INDEX_RANGE
- return elem->index_len *
- ((elem->index_type == GPU_INDEX_U32) ? sizeof(GLuint) : sizeof(GLshort));
-#else
- return elem->index_len * sizeof(GLuint);
-#endif
-}
+/* -------------------------------------------------------------------- */
+/** \name IndexBufBuilder
+ * \{ */
-int GPU_indexbuf_primitive_len(GPUPrimType prim_type)
-{
- switch (prim_type) {
- case GPU_PRIM_POINTS:
- return 1;
- case GPU_PRIM_LINES:
- return 2;
- case GPU_PRIM_TRIS:
- return 3;
- case GPU_PRIM_LINES_ADJ:
- return 4;
- default:
- break;
- }
-#if TRUST_NO_ONE
- assert(false);
-#endif
- return -1;
-}
+using namespace blender;
+using namespace blender::gpu;
void GPU_indexbuf_init_ex(GPUIndexBufBuilder *builder,
GPUPrimType prim_type,
@@ -237,46 +204,69 @@ void GPU_indexbuf_set_tri_restart(GPUIndexBufBuilder *builder, uint elem)
}
}
-GPUIndexBuf *GPU_indexbuf_create_subrange(GPUIndexBuf *elem_src, uint start, uint length)
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Creation & Deletion
+ * \{ */
+
+namespace blender::gpu {
+
+IndexBuf::~IndexBuf()
{
- GPUIndexBuf *elem = (GPUIndexBuf *)MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf");
- GPU_indexbuf_create_subrange_in_place(elem, elem_src, start, length);
- return elem;
+ if (!is_subrange_) {
+ MEM_SAFE_FREE(data_);
+ }
}
-void GPU_indexbuf_create_subrange_in_place(GPUIndexBuf *elem,
- GPUIndexBuf *elem_src,
- uint start,
- uint length)
+void IndexBuf::init(uint indices_len, uint32_t *indices)
{
- BLI_assert(elem_src && !elem_src->is_subrange);
- BLI_assert((length == 0) || (start + length <= elem_src->index_len));
+ is_init_ = true;
+ data_ = indices;
+ index_start_ = 0;
+ index_len_ = indices_len;
+
#if GPU_TRACK_INDEX_RANGE
- elem->index_type = elem_src->index_type;
- elem->gl_index_type = elem_src->gl_index_type;
- elem->base_index = elem_src->base_index;
+ /* Everything remains 32 bit while building to keep things simple.
+ * Find min/max after, then convert to smallest index type possible. */
+ uint min_index, max_index;
+ uint range = this->index_range(&min_index, &max_index);
+ /* count the primitive restart index. */
+ range += 1;
+
+ if (range <= 0xFFFF) {
+ index_type_ = GPU_INDEX_U16;
+ this->squeeze_indices_short(min_index, max_index);
+ }
#endif
- elem->is_subrange = true;
- elem->src = elem_src;
- elem->index_start = start;
- elem->index_len = length;
}
-#if GPU_TRACK_INDEX_RANGE
-/* Everything remains 32 bit while building to keep things simple.
- * Find min/max after, then convert to smallest index type possible. */
+void IndexBuf::init_subrange(IndexBuf *elem_src, uint start, uint length)
+{
+ /* We don't support nested subranges. */
+ BLI_assert(elem_src && elem_src->is_subrange_ == false);
+ BLI_assert((length == 0) || (start + length <= elem_src->index_len_));
+
+ is_init_ = true;
+ is_subrange_ = true;
+ src_ = elem_src;
+ index_start_ = start;
+ index_len_ = length;
+ index_base_ = elem_src->index_base_;
+ index_type_ = elem_src->index_type_;
+}
-static uint index_range(const uint values[], uint value_len, uint *min_out, uint *max_out)
+uint IndexBuf::index_range(uint *r_min, uint *r_max)
{
- if (value_len == 0) {
- *min_out = 0;
- *max_out = 0;
+ if (index_len_ == 0) {
+ *r_min = *r_max = 0;
return 0;
}
+ const uint32_t *uint_idx = (uint32_t *)data_;
uint min_value = RESTART_INDEX;
uint max_value = 0;
- for (uint i = 0; i < value_len; i++) {
- const uint value = values[i];
+ for (uint i = 0; i < index_len_; i++) {
+ const uint value = uint_idx[i];
if (value == RESTART_INDEX) {
continue;
}
@@ -288,120 +278,92 @@ static uint index_range(const uint values[], uint value_len, uint *min_out, uint
}
}
if (min_value == RESTART_INDEX) {
- *min_out = 0;
- *max_out = 0;
+ *r_min = *r_max = 0;
return 0;
}
-
- *min_out = min_value;
- *max_out = max_value;
+ *r_min = min_value;
+ *r_max = max_value;
return max_value - min_value;
}
-static void squeeze_indices_short(GPUIndexBufBuilder *builder,
- GPUIndexBuf *elem,
- uint min_index,
- uint max_index)
+void IndexBuf::squeeze_indices_short(uint min_idx, uint max_idx)
{
- const uint *values = builder->data;
- const uint index_len = elem->index_len;
-
/* data will never be *larger* than builder->data...
* converting in place to avoid extra allocation */
- GLushort *data = (GLushort *)builder->data;
+ uint16_t *ushort_idx = (uint16_t *)data_;
+ const uint32_t *uint_idx = (uint32_t *)data_;
- if (max_index >= 0xFFFF) {
- elem->base_index = min_index;
- for (uint i = 0; i < index_len; i++) {
- data[i] = (values[i] == RESTART_INDEX) ? 0xFFFF : (GLushort)(values[i] - min_index);
+ if (max_idx >= 0xFFFF) {
+ index_base_ = min_idx;
+ for (uint i = 0; i < index_len_; i++) {
+ ushort_idx[i] = (uint16_t)MAX2(0xFFFF, uint_idx[i] - min_idx);
}
}
else {
- elem->base_index = 0;
- for (uint i = 0; i < index_len; i++) {
- data[i] = (GLushort)(values[i]);
+ index_base_ = 0;
+ for (uint i = 0; i < index_len_; i++) {
+ ushort_idx[i] = (uint16_t)(uint_idx[i]);
}
}
}
-#endif /* GPU_TRACK_INDEX_RANGE */
+} // namespace blender::gpu
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name C-API
+ * \{ */
GPUIndexBuf *GPU_indexbuf_calloc(void)
{
- return (GPUIndexBuf *)MEM_callocN(sizeof(GPUIndexBuf), __func__);
+ return wrap(GPUBackend::get()->indexbuf_alloc());
}
GPUIndexBuf *GPU_indexbuf_build(GPUIndexBufBuilder *builder)
{
- GPUIndexBuf *elem = (GPUIndexBuf *)MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf");
+ GPUIndexBuf *elem = GPU_indexbuf_calloc();
GPU_indexbuf_build_in_place(builder, elem);
return elem;
}
-void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *builder, GPUIndexBuf *elem)
+GPUIndexBuf *GPU_indexbuf_create_subrange(GPUIndexBuf *elem_src, uint start, uint length)
{
-#if TRUST_NO_ONE
- assert(builder->data != NULL);
-#endif
- elem->index_len = builder->index_len;
- elem->ibo_id = 0; /* Created at first use. */
-
-#if GPU_TRACK_INDEX_RANGE
- uint min_index, max_index;
- uint range = index_range(builder->data, builder->index_len, &min_index, &max_index);
-
- /* count the primitive restart index. */
- range += 1;
-
- if (range <= 0xFFFF) {
- elem->index_type = GPU_INDEX_U16;
- squeeze_indices_short(builder, elem, min_index, max_index);
- }
- else {
- elem->index_type = GPU_INDEX_U32;
- elem->base_index = 0;
- }
- elem->gl_index_type = convert_index_type_to_gl(elem->index_type);
-#endif
+ GPUIndexBuf *elem = GPU_indexbuf_calloc();
+ GPU_indexbuf_create_subrange_in_place(elem, elem_src, start, length);
+ return elem;
+}
+void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *builder, GPUIndexBuf *elem)
+{
+ BLI_assert(builder->data != NULL);
/* Transfer data ownership to GPUIndexBuf.
* It will be uploaded upon first use. */
- elem->data = builder->data;
- builder->data = NULL;
- /* other fields are safe to leave */
+ unwrap(elem)->init(builder->index_len, builder->data);
+ builder->data = nullptr;
}
-static void indexbuf_upload_data(GPUIndexBuf *elem)
+void GPU_indexbuf_create_subrange_in_place(GPUIndexBuf *elem,
+ GPUIndexBuf *elem_src,
+ uint start,
+ uint length)
{
- /* send data to GPU */
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, GPU_indexbuf_size_get(elem), elem->data, GL_STATIC_DRAW);
- /* No need to keep copy of data in system memory. */
- MEM_freeN(elem->data);
- elem->data = NULL;
+ unwrap(elem)->init_subrange(unwrap(elem_src), start, length);
}
-void GPU_indexbuf_use(GPUIndexBuf *elem)
+void GPU_indexbuf_discard(GPUIndexBuf *elem)
{
- if (elem->is_subrange) {
- GPU_indexbuf_use(elem->src);
- return;
- }
- if (elem->ibo_id == 0) {
- elem->ibo_id = GPU_buf_alloc();
- }
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->ibo_id);
- if (elem->data != NULL) {
- indexbuf_upload_data(elem);
- }
+ delete unwrap(elem);
}
-void GPU_indexbuf_discard(GPUIndexBuf *elem)
+bool GPU_indexbuf_is_init(GPUIndexBuf *elem)
{
- if (elem->ibo_id) {
- GPU_buf_free(elem->ibo_id);
- }
- if (!elem->is_subrange && elem->data) {
- MEM_freeN(elem->data);
- }
- MEM_freeN(elem);
+ return unwrap(elem)->is_init();
}
+
+int GPU_indexbuf_primitive_len(GPUPrimType prim_type)
+{
+ return indices_per_primitive(prim_type);
+}
+
+/** \} */