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
path: root/source
diff options
context:
space:
mode:
authorMike Erwin <significant.bit@gmail.com>2016-10-13 21:49:33 +0300
committerMike Erwin <significant.bit@gmail.com>2016-10-13 22:15:40 +0300
commit945f8e3f93ac3c2dbc8ee0d8504040b6bcaa41b8 (patch)
tree658ba86e25e31b9f78b3d4bd4ca85e6a4377a23e /source
parentdfa5b32c8cc4f9df7da660754eae773f5df102e6 (diff)
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.
Diffstat (limited to 'source')
-rw-r--r--source/blender/gpu/gawain/vertex_format.c48
-rw-r--r--source/blender/gpu/gawain/vertex_format.h6
2 files changed, 36 insertions, 18 deletions
diff --git a/source/blender/gpu/gawain/vertex_format.c b/source/blender/gpu/gawain/vertex_format.c
index a39e3ca2486..20a4d7d8099 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 b58e70fe70a..09c79603b0c 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*);