[Bf-blender-cvs] [a97e5be2aef] tmp-batch-cache-cleanup: GPU: Add vertex format deinterleaving
Clément Foucault
noreply at git.blender.org
Mon Jul 22 12:52:42 CEST 2019
Commit: a97e5be2aef5a5106c8d27188d1aff8ee575ed72
Author: Clément Foucault
Date: Wed Jul 17 00:30:22 2019 +0200
Branches: tmp-batch-cache-cleanup
https://developer.blender.org/rBa97e5be2aef5a5106c8d27188d1aff8ee575ed72
GPU: Add vertex format deinterleaving
This makes it possible to have each attrib use a contiguous portion of the
vertex buffer, making attribute filling much more easy and fast as this is
how they are store in blender Custom Data layers.
===================================================================
M source/blender/gpu/GPU_vertex_format.h
M source/blender/gpu/intern/gpu_batch.c
M source/blender/gpu/intern/gpu_vertex_format.c
M source/blender/gpu/intern/gpu_vertex_format_private.h
===================================================================
diff --git a/source/blender/gpu/GPU_vertex_format.h b/source/blender/gpu/GPU_vertex_format.h
index 68608a98a79..3e851a5e98f 100644
--- a/source/blender/gpu/GPU_vertex_format.h
+++ b/source/blender/gpu/GPU_vertex_format.h
@@ -88,6 +88,8 @@ typedef struct GPUVertFormat {
uint packed : 1;
/** Current offset in names[]. */
uint name_offset : 8;
+ /** Store each attrib in one contiguous buffer region. */
+ uint deinterleaved : 1;
GPUVertAttr attrs[GPU_VERT_ATTR_MAX_LEN];
char names[GPU_VERT_ATTR_NAMES_BUF_LEN];
@@ -104,6 +106,8 @@ uint GPU_vertformat_attr_add(
GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode);
void GPU_vertformat_alias_add(GPUVertFormat *, const char *alias);
+void GPU_vertformat_deinterleave(GPUVertFormat *format);
+
int GPU_vertformat_attr_id_get(const GPUVertFormat *, const char *name);
BLI_INLINE const char *GPU_vertformat_attr_name_get(const GPUVertFormat *format,
diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c
index 8d6e0aadb61..196a8a0f3b9 100644
--- a/source/blender/gpu/intern/gpu_batch.c
+++ b/source/blender/gpu/intern/gpu_batch.c
@@ -380,13 +380,23 @@ static void create_bindings(GPUVertBuf *verts,
const GPUVertFormat *format = &verts->format;
const uint attr_len = format->attr_len;
- const uint stride = format->stride;
+ uint stride = format->stride;
+ uint offset = 0;
GPU_vertbuf_use(verts);
for (uint a_idx = 0; a_idx < attr_len; ++a_idx) {
const GPUVertAttr *a = &format->attrs[a_idx];
- const GLvoid *pointer = (const GLubyte *)0 + a->offset + v_first * stride;
+
+ if (format->deinterleaved) {
+ offset += ((a_idx == 0) ? 0 : format->attrs[a_idx - 1].sz) * verts->vertex_len;
+ stride = a->sz;
+ }
+ else {
+ offset = a->offset;
+ }
+
+ const GLvoid *pointer = (const GLubyte *)0 + offset + v_first * stride;
for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) {
const char *name = GPU_vertformat_attr_name_get(format, a, n_idx);
diff --git a/source/blender/gpu/intern/gpu_vertex_format.c b/source/blender/gpu/intern/gpu_vertex_format.c
index e745c525df6..e6af6029fc5 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.c
+++ b/source/blender/gpu/intern/gpu_vertex_format.c
@@ -216,6 +216,29 @@ int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const char *name)
return -1;
}
+/* Make attribute layout non-interleaved.
+ * Warning! This does not change data layout!
+ * Use direct buffer access to fill the data.
+ * This is for advanced usage.
+ *
+ * Deinterleaved data means all attrib data for each attrib
+ * is stored continuously like this :
+ * 000011112222
+ * instead of :
+ * 012012012012
+ *
+ * Note this is per attrib deinterleaving, NOT per component.
+ * */
+void GPU_vertformat_deinterleave(GPUVertFormat *format)
+{
+ /* Ideally we should change the stride and offset here. This would allow
+ * us to use GPU_vertbuf_attr_set / GPU_vertbuf_attr_fill. But since
+ * we use only 11 bits for attr->offset this limits the size of the
+ * buffer considerably. So instead we do the conversion when creating
+ * bindings in create_bindings(). */
+ format->deinterleaved = true;
+}
+
uint padding(uint offset, uint alignment)
{
const uint mod = offset % alignment;
diff --git a/source/blender/gpu/intern/gpu_vertex_format_private.h b/source/blender/gpu/intern/gpu_vertex_format_private.h
index a850d17a1dd..13459101669 100644
--- a/source/blender/gpu/intern/gpu_vertex_format_private.h
+++ b/source/blender/gpu/intern/gpu_vertex_format_private.h
@@ -27,6 +27,7 @@
#define __GPU_VERTEX_FORMAT_PRIVATE_H__
void VertexFormat_pack(GPUVertFormat *format);
+void VertexFormat_deinterleave(GPUVertFormat *format, uint vertex_len);
uint padding(uint offset, uint alignment);
uint vertex_buffer_size(const GPUVertFormat *format, uint vertex_len);
More information about the Bf-blender-cvs
mailing list