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*);

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to