[Bf-blender-cvs] [945f8e3] blender2.8: Gawain: vertex format now uses fixed allocations (CPU perf++)

Mike Erwin noreply at git.blender.org
Thu Oct 13 21:18:47 CEST 2016


Commit: 945f8e3f93ac3c2dbc8ee0d8504040b6bcaa41b8
Author: Mike Erwin
Date:   Thu Oct 13 14:49:33 2016 -0400
Branches: blender2.8
https://developer.blender.org/rB945f8e3f93ac3c2dbc8ee0d8504040b6bcaa41b8

Gawain: vertex format now uses fixed allocations (CPU perf++)

API stays exactly the same.

Attribute names can still be of variable length, as long as the average length does not exceed AVG_VERTEX_ATTRIB_NAME_LEN. Since this includes unused attributes (length = 0) the current avg of 5 might even be too high.

===================================================================

M	source/blender/gpu/gawain/vertex_format.c
M	source/blender/gpu/gawain/vertex_format.h

===================================================================

diff --git a/source/blender/gpu/gawain/vertex_format.c b/source/blender/gpu/gawain/vertex_format.c
index a39e3ca..20a4d7d 100644
--- a/source/blender/gpu/gawain/vertex_format.c
+++ b/source/blender/gpu/gawain/vertex_format.c
@@ -21,29 +21,19 @@
 
 void VertexFormat_clear(VertexFormat* format)
 	{
-	for (unsigned a = 0; a < format->attrib_ct; ++a)
-		free(format->attribs[a].name);
-
 #if TRUST_NO_ONE
 	memset(format, 0, sizeof(VertexFormat));
 #else
 	format->attrib_ct = 0;
 	format->packed = false;
+	format->name_offset = 0;
 #endif
 	}
 
 void VertexFormat_copy(VertexFormat* dest, const VertexFormat* src)
 	{
-	// discard dest format's old name strings
-	for (unsigned a = 0; a < dest->attrib_ct; ++a)
-		free(dest->attribs[a].name);
-
 	// copy regular struct fields
 	memcpy(dest, src, sizeof(VertexFormat));
-	
-	// give dest attribs their own copy of name strings
-	for (unsigned i = 0; i < src->attrib_ct; ++i)
-		dest->attribs[i].name = strdup(src->attribs[i].name);
 	}
 
 static unsigned comp_sz(GLenum type)
@@ -79,6 +69,33 @@ unsigned vertex_buffer_size(const VertexFormat* format, unsigned vertex_ct)
 	return format->stride * vertex_ct;
 	}
 
+static const char* copy_attrib_name(VertexFormat* format, const char* name)
+	{
+	// strncpy does 110% of what we need; let's do exactly 100%
+	char* name_copy = format->names + format->name_offset;
+	unsigned available = VERTEX_ATTRIB_NAMES_BUFFER_LEN - format->name_offset;
+	bool terminated = false;
+
+	for (unsigned i = 0; i < available; ++i)
+		{
+		const char c = name[i];
+		name_copy[i] = c;
+		if (c == '\0')
+			{
+			terminated = true;
+			format->name_offset += (i + 1);
+			break;
+			}
+		}
+
+#if TRUST_NO_ONE
+	assert(terminated);
+	assert(format->name_offset <= VERTEX_ATTRIB_NAMES_BUFFER_LEN);
+#endif
+
+	return name_copy;
+	}
+
 unsigned add_attrib(VertexFormat* format, const char* name, GLenum comp_type, unsigned comp_ct, VertexFetchMode fetch_mode)
 	{
 #if TRUST_NO_ONE
@@ -114,7 +131,7 @@ unsigned add_attrib(VertexFormat* format, const char* name, GLenum comp_type, un
 	const unsigned attrib_id = format->attrib_ct++;
 	Attrib* attrib = format->attribs + attrib_id;
 
-	attrib->name = strdup(name);
+	attrib->name = copy_attrib_name(format, name);
 	attrib->comp_type = comp_type;
 	attrib->comp_ct = comp_ct;
 	attrib->sz = attrib_sz(attrib);
@@ -149,11 +166,8 @@ void VertexFormat_pack(VertexFormat* format)
 	// later we can implement more efficient packing w/ reordering
 	// (keep attrib ID order, adjust their offsets to reorder in buffer)
 
-	// TODO: concatentate name strings into attribs[0].name, point attribs[i] to
-	// offset into the combined string. Free all other name strings. Could save more
-	// space by storing combined string in VertexFormat, with each attrib having an
-	// offset into it. Could also append each name string as it's added... pack()
-	// could alloc just enough to hold the final combo string. And just enough to
+	// TODO:
+	// realloc just enough to hold the final combo string. And just enough to
 	// hold used attribs, not all 16.
 
 	Attrib* a0 = format->attribs + 0;
diff --git a/source/blender/gpu/gawain/vertex_format.h b/source/blender/gpu/gawain/vertex_format.h
index b58e70f..09c7960 100644
--- a/source/blender/gpu/gawain/vertex_format.h
+++ b/source/blender/gpu/gawain/vertex_format.h
@@ -14,6 +14,8 @@
 #include "common.h"
 
 #define MAX_VERTEX_ATTRIBS 16
+#define AVG_VERTEX_ATTRIB_NAME_LEN 5
+#define VERTEX_ATTRIB_NAMES_BUFFER_LEN ((AVG_VERTEX_ATTRIB_NAME_LEN + 1) * MAX_VERTEX_ATTRIBS)
 
 typedef enum {
 	KEEP_FLOAT,
@@ -28,7 +30,7 @@ typedef struct {
 	unsigned sz; // size in bytes, 1 to 16
 	unsigned offset; // from beginning of vertex, in bytes
 	VertexFetchMode fetch_mode;
-	char* name; // TODO: shared allocation of all names within a VertexFormat
+	const char* name;
 } Attrib;
 
 typedef struct {
@@ -36,6 +38,8 @@ typedef struct {
 	unsigned stride; // stride in bytes, 1 to 256
 	bool packed;
 	Attrib attribs[MAX_VERTEX_ATTRIBS]; // TODO: variable-size attribs array
+	char names[VERTEX_ATTRIB_NAMES_BUFFER_LEN];
+	unsigned name_offset;
 } VertexFormat;
 
 void VertexFormat_clear(VertexFormat*);




More information about the Bf-blender-cvs mailing list