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>2018-02-14 19:59:48 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-02-14 20:59:42 +0300
commitab7e7a005bde711d14493d51ee26ea297fa99e47 (patch)
tree8ba24ec2fa94bf443df481f3ec5e3e769dc7f83c /intern/gawain
parent1e9ef2a25e08462a020de3897bc3b68a782c4120 (diff)
GWN: Add new dynamic type of batches and remove
Theses batches keeps their memory chuck allocated after transfer to be reused and updated very often. NOTE: This commit break instancing in DRW. (it's fixed in the next commit)
Diffstat (limited to 'intern/gawain')
-rw-r--r--intern/gawain/gawain/gwn_vertex_buffer.h13
-rw-r--r--intern/gawain/src/gwn_vertex_buffer.c97
2 files changed, 73 insertions, 37 deletions
diff --git a/intern/gawain/gawain/gwn_vertex_buffer.h b/intern/gawain/gawain/gwn_vertex_buffer.h
index 50a4e1aa2f6..34f12754f40 100644
--- a/intern/gawain/gawain/gwn_vertex_buffer.h
+++ b/intern/gawain/gawain/gwn_vertex_buffer.h
@@ -13,6 +13,7 @@
#include "gwn_vertex_format.h"
+#define VRAM_USAGE 1
// How to create a Gwn_VertBuf:
// 1) verts = GWN_vertbuf_create() or GWN_vertbuf_init(verts)
// 2) GWN_vertformat_attr_add(verts->format, ...)
@@ -24,15 +25,22 @@
typedef struct Gwn_VertBuf {
Gwn_VertFormat format;
unsigned vertex_ct;
- bool own_data; // does gawain own the data an is able to free it
+ unsigned alloc_ct; // size in vertex of alloced data
+#if VRAM_USAGE
+ unsigned vram_size; // size in byte of data present in the VRAM
+#endif
+ unsigned data_dirty : 1; // does the data has been touched since last transfert
+ unsigned data_dynamic : 1; // do we keep the RAM allocation for further updates?
+ unsigned data_resized : 1; // does the data has been resized since last transfert
GLubyte* data; // NULL indicates data in VRAM (unmapped) or not yet allocated
GLuint vbo_id; // 0 indicates not yet sent to VRAM
} Gwn_VertBuf;
Gwn_VertBuf* GWN_vertbuf_create(void);
Gwn_VertBuf* GWN_vertbuf_create_with_format(const Gwn_VertFormat*);
+Gwn_VertBuf* GWN_vertbuf_create_dynamic_with_format(const Gwn_VertFormat*);
-void GWN_vertbuf_clear(Gwn_VertBuf* verts);
+void GWN_vertbuf_clear(Gwn_VertBuf*);
void GWN_vertbuf_discard(Gwn_VertBuf*);
void GWN_vertbuf_init(Gwn_VertBuf*);
@@ -40,7 +48,6 @@ void GWN_vertbuf_init_with_format(Gwn_VertBuf*, const Gwn_VertFormat*);
unsigned GWN_vertbuf_size_get(const Gwn_VertBuf*);
void GWN_vertbuf_data_alloc(Gwn_VertBuf*, unsigned v_ct);
-void GWN_vertbuf_data_set(Gwn_VertBuf*, unsigned v_ct, void* data, bool pass_ownership);
void GWN_vertbuf_data_resize(Gwn_VertBuf*, unsigned v_ct);
// The most important set_attrib variant is the untyped one. Get it right first.
diff --git a/intern/gawain/src/gwn_vertex_buffer.c b/intern/gawain/src/gwn_vertex_buffer.c
index 2bab0bc378b..32bef765390 100644
--- a/intern/gawain/src/gwn_vertex_buffer.c
+++ b/intern/gawain/src/gwn_vertex_buffer.c
@@ -38,6 +38,13 @@ Gwn_VertBuf* GWN_vertbuf_create_with_format(const Gwn_VertFormat* format)
// TODO: implement those memory savings
}
+Gwn_VertBuf* GWN_vertbuf_create_dynamic_with_format(const Gwn_VertFormat* format)
+ {
+ Gwn_VertBuf* verts = GWN_vertbuf_create_with_format(format);
+ verts->data_dynamic = true;
+ return verts;
+ }
+
void GWN_vertbuf_init(Gwn_VertBuf* verts)
{
memset(verts, 0, sizeof(Gwn_VertBuf));
@@ -58,12 +65,12 @@ void GWN_vertbuf_clear(Gwn_VertBuf* verts)
{
if (verts->vbo_id) {
GWN_buf_id_free(verts->vbo_id);
- vbo_memory_usage -= GWN_vertbuf_size_get(verts);
- }
-#if KEEP_SINGLE_COPY
- else
+#if VRAM_USAGE
+ vbo_memory_usage -= verts->vram_size;
#endif
- if (verts->data && verts->own_data)
+ }
+
+ if (verts->data)
{
free(verts->data);
verts->data = NULL;
@@ -75,12 +82,12 @@ void GWN_vertbuf_discard(Gwn_VertBuf* verts)
if (verts->vbo_id)
{
GWN_buf_id_free(verts->vbo_id);
- vbo_memory_usage -= GWN_vertbuf_size_get(verts);
- }
-#if KEEP_SINGLE_COPY
- else
+#if VRAM_USAGE
+ vbo_memory_usage -= verts->vram_size;
#endif
- if (verts->data && verts->own_data)
+ }
+
+ if (verts->data)
{
free(verts->data);
}
@@ -101,33 +108,22 @@ void GWN_vertbuf_data_alloc(Gwn_VertBuf* verts, unsigned v_ct)
VertexFormat_pack(format);
verts->vertex_ct = v_ct;
- verts->own_data = true;
// Data initially lives in main memory. Will be transferred to VRAM when we "prime" it.
verts->data = malloc(GWN_vertbuf_size_get(verts));
}
-void GWN_vertbuf_data_set(Gwn_VertBuf* verts, unsigned v_ct, void* data, bool pass_ownership)
- {
- Gwn_VertFormat* format = &verts->format;
- if (!format->packed)
- VertexFormat_pack(format);
-
- verts->vertex_ct = v_ct;
- verts->own_data = pass_ownership;
-
- // Data initially lives in main memory. Will be transferred to VRAM when we "prime" it.
- verts->data = data;
- }
-
void GWN_vertbuf_data_resize(Gwn_VertBuf* verts, unsigned v_ct)
{
#if TRUST_NO_ONE
assert(verts->vertex_ct != v_ct); // allow this?
assert(verts->data != NULL); // has already been allocated
- assert(verts->vbo_id == 0); // has not been sent to VRAM
+ assert(verts->vbo_id == 0 || verts->data_dynamic); // has not been sent to VRAM
#endif
+ // for dynamic buffers
+ verts->data_resized = true;
+
verts->vertex_ct = v_ct;
verts->data = realloc(verts->data, GWN_vertbuf_size_get(verts));
// TODO: skip realloc if v_ct < existing vertex count
@@ -139,6 +135,8 @@ void GWN_vertbuf_attr_set(Gwn_VertBuf* verts, unsigned a_idx, unsigned v_idx, co
const Gwn_VertFormat* format = &verts->format;
const Gwn_VertAttr* a = format->attribs + a_idx;
+ verts->data_dirty = true;
+
#if TRUST_NO_ONE
assert(a_idx < format->attrib_ct);
assert(v_idx < verts->vertex_ct);
@@ -153,6 +151,8 @@ void GWN_vertbuf_attr_fill(Gwn_VertBuf* verts, unsigned a_idx, const void* data)
const Gwn_VertFormat* format = &verts->format;
const Gwn_VertAttr* a = format->attribs + a_idx;
+ verts->data_dirty = true;
+
#if TRUST_NO_ONE
assert(a_idx < format->attrib_ct);
#endif
@@ -167,6 +167,8 @@ void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf* verts, unsigned a_idx, unsigned s
const Gwn_VertFormat* format = &verts->format;
const Gwn_VertAttr* a = format->attribs + a_idx;
+ verts->data_dirty = true;
+
#if TRUST_NO_ONE
assert(a_idx < format->attrib_ct);
assert(verts->data != NULL); // data must be in main mem
@@ -209,31 +211,58 @@ void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf* verts, unsigned a_idx, Gwn_VertB
static void VertexBuffer_prime(Gwn_VertBuf* verts)
{
- const unsigned buffer_sz = GWN_vertbuf_size_get(verts);
+ unsigned buffer_sz = GWN_vertbuf_size_get(verts);
+
+#if VRAM_USAGE
+ vbo_memory_usage += buffer_sz;
+ verts->vram_size = buffer_sz;
+#endif
verts->vbo_id = GWN_buf_id_alloc();
glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id);
// fill with delicious data & send to GPU the first time only
- glBufferData(GL_ARRAY_BUFFER, buffer_sz, verts->data, GL_STATIC_DRAW);
-
- vbo_memory_usage += buffer_sz;
+ glBufferData(GL_ARRAY_BUFFER, verts->vram_size, verts->data, (verts->data_dynamic) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
-#if KEEP_SINGLE_COPY
// now that GL has a copy, discard original
- if (verts->own_data)
+ if (!verts->data_dynamic)
{
free(verts->data);
verts->data = NULL;
}
+
+ verts->data_dirty = false;
+ }
+
+static void VertexBuffer_update(Gwn_VertBuf* verts)
+ {
+ unsigned buffer_sz = GWN_vertbuf_size_get(verts);
+
+#if VRAM_USAGE
+ vbo_memory_usage -= verts->vram_size;
+ vbo_memory_usage += buffer_sz;
+ verts->vram_size = buffer_sz;
#endif
+
+ glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id);
+
+ // fill with delicious data & send to GPU ... AGAIN
+ if (verts->data_resized)
+ glBufferData(GL_ARRAY_BUFFER, buffer_sz, verts->data, GL_DYNAMIC_DRAW);
+ else
+ glBufferSubData(GL_ARRAY_BUFFER, 0, buffer_sz, verts->data); // .. todo try glMapBuffer
+
+ verts->data_dirty = false;
+ verts->data_resized = false;
}
void GWN_vertbuf_use(Gwn_VertBuf* verts)
{
- if (verts->vbo_id)
- glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id);
- else
+ if (!verts->vbo_id)
VertexBuffer_prime(verts);
+ else if (verts->data_dirty)
+ VertexBuffer_update(verts);
+ else
+ glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id);
}
unsigned GWN_vertbuf_get_memory_usage(void)