GPUVertexFormat: Reduce size of structs
With this patch, the size of GPUVertFormat goes from 1240 to 388.
This commit is contained in:
@@ -404,7 +404,6 @@ void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv(ListBase *lb,
|
|||||||
&format_pos_nor, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
&format_pos_nor, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||||
attr_id.nor = GPU_vertformat_attr_add(
|
attr_id.nor = GPU_vertformat_attr_add(
|
||||||
&format_pos_nor, "nor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
&format_pos_nor, "nor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||||
GPU_vertformat_triple_load(&format_pos_nor);
|
|
||||||
/* UVs are in [0..1] range. We can compress them. */
|
/* UVs are in [0..1] range. We can compress them. */
|
||||||
attr_id.uv = GPU_vertformat_attr_add(
|
attr_id.uv = GPU_vertformat_attr_add(
|
||||||
&format_uv, "u", GPU_COMP_I16, 2, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
&format_uv, "u", GPU_COMP_I16, 2, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||||
|
@@ -48,12 +48,17 @@ typedef enum {
|
|||||||
|
|
||||||
typedef struct GPUVertBuf {
|
typedef struct GPUVertBuf {
|
||||||
GPUVertFormat format;
|
GPUVertFormat format;
|
||||||
uint vertex_len; /* number of verts we want to draw */
|
/** Number of verts we want to draw. */
|
||||||
uint vertex_alloc; /* number of verts data */
|
uint vertex_len;
|
||||||
bool dirty;
|
/** Number of verts data. */
|
||||||
|
uint vertex_alloc;
|
||||||
|
/** 0 indicates not yet allocated. */
|
||||||
|
uint32_t vbo_id;
|
||||||
|
/** Usage hint for GL optimisation. */
|
||||||
|
uint usage : 2;
|
||||||
|
/** Data has been touched and need to be reuploaded to GPU. */
|
||||||
|
uint dirty : 1;
|
||||||
unsigned char *data; /* NULL indicates data in VRAM (unmapped) */
|
unsigned char *data; /* NULL indicates data in VRAM (unmapped) */
|
||||||
uint32_t vbo_id; /* 0 indicates not yet allocated */
|
|
||||||
GPUUsageType usage; /* usage hint for GL optimisation */
|
|
||||||
} GPUVertBuf;
|
} GPUVertBuf;
|
||||||
|
|
||||||
GPUVertBuf *GPU_vertbuf_create(GPUUsageType);
|
GPUVertBuf *GPU_vertbuf_create(GPUUsageType);
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#define __GPU_VERTEX_FORMAT_H__
|
#define __GPU_VERTEX_FORMAT_H__
|
||||||
|
|
||||||
#include "GPU_common.h"
|
#include "GPU_common.h"
|
||||||
|
#include "BLI_compiler_compat.h"
|
||||||
|
|
||||||
#define GPU_VERT_ATTR_MAX_LEN 16
|
#define GPU_VERT_ATTR_MAX_LEN 16
|
||||||
#define GPU_VERT_ATTR_MAX_NAMES 4
|
#define GPU_VERT_ATTR_MAX_NAMES 4
|
||||||
@@ -54,28 +55,35 @@ typedef enum {
|
|||||||
} GPUVertFetchMode;
|
} GPUVertFetchMode;
|
||||||
|
|
||||||
typedef struct GPUVertAttr {
|
typedef struct GPUVertAttr {
|
||||||
GPUVertFetchMode fetch_mode;
|
GPUVertFetchMode fetch_mode : 2;
|
||||||
GPUVertCompType comp_type;
|
GPUVertCompType comp_type : 3;
|
||||||
|
/* 1 to 4 or 8 or 12 or 16 */
|
||||||
|
uint comp_len : 5;
|
||||||
|
/* size in bytes, 1 to 64 */
|
||||||
|
uint sz : 7;
|
||||||
|
/* from beginning of vertex, in bytes */
|
||||||
|
uint offset : 11;
|
||||||
|
/* up to GPU_VERT_ATTR_MAX_NAMES */
|
||||||
|
uint name_len : 3;
|
||||||
uint gl_comp_type;
|
uint gl_comp_type;
|
||||||
uint comp_len; /* 1 to 4 or 8 or 12 or 16 */
|
/* -- 8 Bytes -- */
|
||||||
uint sz; /* size in bytes, 1 to 64 */
|
uchar names[GPU_VERT_ATTR_MAX_NAMES];
|
||||||
uint offset; /* from beginning of vertex, in bytes */
|
|
||||||
uint name_len; /* up to GPU_VERT_ATTR_MAX_NAMES */
|
|
||||||
const char *name[GPU_VERT_ATTR_MAX_NAMES];
|
|
||||||
} GPUVertAttr;
|
} GPUVertAttr;
|
||||||
|
|
||||||
typedef struct GPUVertFormat {
|
typedef struct GPUVertFormat {
|
||||||
/** 0 to 16 (GPU_VERT_ATTR_MAX_LEN). */
|
/** 0 to 16 (GPU_VERT_ATTR_MAX_LEN). */
|
||||||
uint attr_len;
|
uint attr_len : 5;
|
||||||
/** Total count of active vertex attribute. */
|
/** Total count of active vertex attribute. */
|
||||||
uint name_len;
|
uint name_len : 5;
|
||||||
/** Stride in bytes, 1 to 256. */
|
/** Stride in bytes, 1 to 1024. */
|
||||||
uint stride;
|
uint stride : 11;
|
||||||
uint name_offset;
|
/** Has the format been packed. */
|
||||||
bool packed;
|
uint packed : 1;
|
||||||
char names[GPU_VERT_ATTR_NAMES_BUF_LEN];
|
/** Current offset in names[]. */
|
||||||
/** TODO: variable-size array */
|
uint name_offset : 8;
|
||||||
|
|
||||||
GPUVertAttr attrs[GPU_VERT_ATTR_MAX_LEN];
|
GPUVertAttr attrs[GPU_VERT_ATTR_MAX_LEN];
|
||||||
|
char names[GPU_VERT_ATTR_NAMES_BUF_LEN];
|
||||||
} GPUVertFormat;
|
} GPUVertFormat;
|
||||||
|
|
||||||
struct GPUShaderInterface;
|
struct GPUShaderInterface;
|
||||||
@@ -88,18 +96,15 @@ void GPU_vertformat_from_interface(GPUVertFormat *format,
|
|||||||
uint GPU_vertformat_attr_add(
|
uint GPU_vertformat_attr_add(
|
||||||
GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode);
|
GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode);
|
||||||
void GPU_vertformat_alias_add(GPUVertFormat *, const char *alias);
|
void GPU_vertformat_alias_add(GPUVertFormat *, const char *alias);
|
||||||
|
|
||||||
int GPU_vertformat_attr_id_get(const GPUVertFormat *, const char *name);
|
int GPU_vertformat_attr_id_get(const GPUVertFormat *, const char *name);
|
||||||
|
|
||||||
/**
|
BLI_INLINE const char *GPU_vertformat_attr_name_get(const GPUVertFormat *format,
|
||||||
* This makes the "virtual" attributes with suffixes "0", "1", "2"
|
const GPUVertAttr *attr,
|
||||||
* to access triangle data in the vertex shader.
|
uint n_idx)
|
||||||
*
|
{
|
||||||
* IMPORTANT:
|
return format->names + attr->names[n_idx];
|
||||||
* - Call this before creating the vertex buffer and after creating all attributes
|
}
|
||||||
* - Only first vertex out of 3 has the correct information.
|
|
||||||
* Use flat output with #GL_FIRST_VERTEX_CONVENTION.
|
|
||||||
*/
|
|
||||||
void GPU_vertformat_triple_load(GPUVertFormat *format);
|
|
||||||
|
|
||||||
/* format conversion */
|
/* format conversion */
|
||||||
|
|
||||||
|
@@ -70,7 +70,8 @@ void get_attr_locations(const GPUVertFormat *format,
|
|||||||
for (uint a_idx = 0; a_idx < format->attr_len; ++a_idx) {
|
for (uint a_idx = 0; a_idx < format->attr_len; ++a_idx) {
|
||||||
const GPUVertAttr *a = &format->attrs[a_idx];
|
const GPUVertAttr *a = &format->attrs[a_idx];
|
||||||
for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) {
|
for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) {
|
||||||
const GPUShaderInput *input = GPU_shaderinterface_attr(shaderface, a->name[n_idx]);
|
const char *name = GPU_vertformat_attr_name_get(format, a, n_idx);
|
||||||
|
const GPUShaderInput *input = GPU_shaderinterface_attr(shaderface, name);
|
||||||
#if TRUST_NO_ONE
|
#if TRUST_NO_ONE
|
||||||
assert(input != NULL);
|
assert(input != NULL);
|
||||||
/* TODO: make this a recoverable runtime error?
|
/* TODO: make this a recoverable runtime error?
|
||||||
|
@@ -370,7 +370,8 @@ static void create_bindings(GPUVertBuf *verts,
|
|||||||
const GLvoid *pointer = (const GLubyte *)0 + a->offset + v_first * stride;
|
const GLvoid *pointer = (const GLubyte *)0 + a->offset + v_first * stride;
|
||||||
|
|
||||||
for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) {
|
for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) {
|
||||||
const GPUShaderInput *input = GPU_shaderinterface_attr(interface, a->name[n_idx]);
|
const char *name = GPU_vertformat_attr_name_get(format, a, n_idx);
|
||||||
|
const GPUShaderInput *input = GPU_shaderinterface_attr(interface, name);
|
||||||
|
|
||||||
if (input == NULL) {
|
if (input == NULL) {
|
||||||
continue;
|
continue;
|
||||||
|
@@ -58,12 +58,6 @@ void GPU_vertformat_copy(GPUVertFormat *dest, const GPUVertFormat *src)
|
|||||||
{
|
{
|
||||||
/* copy regular struct fields */
|
/* copy regular struct fields */
|
||||||
memcpy(dest, src, sizeof(GPUVertFormat));
|
memcpy(dest, src, sizeof(GPUVertFormat));
|
||||||
|
|
||||||
for (uint i = 0; i < dest->attr_len; i++) {
|
|
||||||
for (uint j = 0; j < dest->attrs[i].name_len; j++) {
|
|
||||||
dest->attrs[i].name[j] = (char *)dest + (src->attrs[i].name[j] - ((char *)src));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLenum convert_comp_type_to_gl(GPUVertCompType type)
|
static GLenum convert_comp_type_to_gl(GPUVertCompType type)
|
||||||
@@ -122,32 +116,20 @@ uint vertex_buffer_size(const GPUVertFormat *format, uint vertex_len)
|
|||||||
return format->stride * vertex_len;
|
return format->stride * vertex_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *copy_attr_name(GPUVertFormat *format, const char *name, const char *suffix)
|
static const char copy_attr_name(GPUVertFormat *format, const char *name)
|
||||||
{
|
{
|
||||||
/* strncpy does 110% of what we need; let's do exactly 100% */
|
/* strncpy does 110% of what we need; let's do exactly 100% */
|
||||||
char *name_copy = format->names + format->name_offset;
|
uchar name_offset = format->name_offset;
|
||||||
uint available = GPU_VERT_ATTR_NAMES_BUF_LEN - format->name_offset;
|
char *name_copy = format->names + name_offset;
|
||||||
|
uint available = GPU_VERT_ATTR_NAMES_BUF_LEN - name_offset;
|
||||||
bool terminated = false;
|
bool terminated = false;
|
||||||
|
|
||||||
for (uint i = 0; i < available; ++i) {
|
for (uint i = 0; i < available; ++i) {
|
||||||
const char c = name[i];
|
const char c = name[i];
|
||||||
name_copy[i] = c;
|
name_copy[i] = c;
|
||||||
if (c == '\0') {
|
if (c == '\0') {
|
||||||
if (suffix) {
|
terminated = true;
|
||||||
for (uint j = 0; j < available; ++j) {
|
format->name_offset += (i + 1);
|
||||||
const char s = suffix[j];
|
|
||||||
name_copy[i + j] = s;
|
|
||||||
if (s == '\0') {
|
|
||||||
terminated = true;
|
|
||||||
format->name_offset += (i + j + 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
terminated = true;
|
|
||||||
format->name_offset += (i + 1);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -157,7 +139,7 @@ static const char *copy_attr_name(GPUVertFormat *format, const char *name, const
|
|||||||
#else
|
#else
|
||||||
(void)terminated;
|
(void)terminated;
|
||||||
#endif
|
#endif
|
||||||
return name_copy;
|
return name_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint GPU_vertformat_attr_add(GPUVertFormat *format,
|
uint GPU_vertformat_attr_add(GPUVertFormat *format,
|
||||||
@@ -196,7 +178,7 @@ uint GPU_vertformat_attr_add(GPUVertFormat *format,
|
|||||||
const uint attr_id = format->attr_len++;
|
const uint attr_id = format->attr_len++;
|
||||||
GPUVertAttr *attr = &format->attrs[attr_id];
|
GPUVertAttr *attr = &format->attrs[attr_id];
|
||||||
|
|
||||||
attr->name[attr->name_len++] = copy_attr_name(format, name, NULL);
|
attr->names[attr->name_len++] = copy_attr_name(format, name);
|
||||||
attr->comp_type = comp_type;
|
attr->comp_type = comp_type;
|
||||||
attr->gl_comp_type = convert_comp_type_to_gl(comp_type);
|
attr->gl_comp_type = convert_comp_type_to_gl(comp_type);
|
||||||
attr->comp_len = (comp_type == GPU_COMP_I10) ?
|
attr->comp_len = (comp_type == GPU_COMP_I10) ?
|
||||||
@@ -217,7 +199,7 @@ void GPU_vertformat_alias_add(GPUVertFormat *format, const char *alias)
|
|||||||
assert(attr->name_len < GPU_VERT_ATTR_MAX_NAMES);
|
assert(attr->name_len < GPU_VERT_ATTR_MAX_NAMES);
|
||||||
#endif
|
#endif
|
||||||
format->name_len++; /* multiname support */
|
format->name_len++; /* multiname support */
|
||||||
attr->name[attr->name_len++] = copy_attr_name(format, alias, NULL);
|
attr->names[attr->name_len++] = copy_attr_name(format, alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const char *name)
|
int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const char *name)
|
||||||
@@ -225,7 +207,8 @@ int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const char *name)
|
|||||||
for (int i = 0; i < format->attr_len; i++) {
|
for (int i = 0; i < format->attr_len; i++) {
|
||||||
const GPUVertAttr *attr = &format->attrs[i];
|
const GPUVertAttr *attr = &format->attrs[i];
|
||||||
for (int j = 0; j < attr->name_len; j++) {
|
for (int j = 0; j < attr->name_len; j++) {
|
||||||
if (STREQ(name, attr->name[j])) {
|
const char *attr_name = GPU_vertformat_attr_name_get(format, attr, j);
|
||||||
|
if (STREQ(name, attr_name)) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -233,41 +216,6 @@ int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const char *name)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_vertformat_triple_load(GPUVertFormat *format)
|
|
||||||
{
|
|
||||||
#if TRUST_NO_ONE
|
|
||||||
assert(!format->packed);
|
|
||||||
assert(format->attr_len * 3 < GPU_VERT_ATTR_MAX_LEN);
|
|
||||||
assert(format->name_len + format->attr_len * 3 < GPU_VERT_ATTR_MAX_LEN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VertexFormat_pack(format);
|
|
||||||
|
|
||||||
uint old_attr_len = format->attr_len;
|
|
||||||
for (uint a_idx = 0; a_idx < old_attr_len; ++a_idx) {
|
|
||||||
GPUVertAttr *attr = &format->attrs[a_idx];
|
|
||||||
/* Duplicate attr twice */
|
|
||||||
for (int i = 1; i < 3; ++i) {
|
|
||||||
GPUVertAttr *dst_attr = &format->attrs[format->attr_len];
|
|
||||||
memcpy(dst_attr, attr, sizeof(GPUVertAttr));
|
|
||||||
/* Increase offset to the next vertex. */
|
|
||||||
dst_attr->offset += format->stride * i;
|
|
||||||
/* Only copy first name for now. */
|
|
||||||
dst_attr->name_len = 0;
|
|
||||||
dst_attr->name[dst_attr->name_len++] = copy_attr_name(
|
|
||||||
format, attr->name[0], (i == 1) ? "1" : "2");
|
|
||||||
format->attr_len++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if TRUST_NO_ONE
|
|
||||||
assert(attr->name_len < GPU_VERT_ATTR_MAX_NAMES);
|
|
||||||
#endif
|
|
||||||
/* Add alias to first attr. */
|
|
||||||
format->name_len++;
|
|
||||||
attr->name[attr->name_len++] = copy_attr_name(format, attr->name[0], "0");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint padding(uint offset, uint alignment)
|
uint padding(uint offset, uint alignment)
|
||||||
{
|
{
|
||||||
const uint mod = offset % alignment;
|
const uint mod = offset % alignment;
|
||||||
@@ -364,7 +312,6 @@ static uint calc_input_component_size(const GPUShaderInput *input)
|
|||||||
|
|
||||||
static void get_fetch_mode_and_comp_type(int gl_type,
|
static void get_fetch_mode_and_comp_type(int gl_type,
|
||||||
GPUVertCompType *r_comp_type,
|
GPUVertCompType *r_comp_type,
|
||||||
uint *r_gl_comp_type,
|
|
||||||
GPUVertFetchMode *r_fetch_mode)
|
GPUVertFetchMode *r_fetch_mode)
|
||||||
{
|
{
|
||||||
switch (gl_type) {
|
switch (gl_type) {
|
||||||
@@ -382,7 +329,6 @@ static void get_fetch_mode_and_comp_type(int gl_type,
|
|||||||
case GL_FLOAT_MAT4x2:
|
case GL_FLOAT_MAT4x2:
|
||||||
case GL_FLOAT_MAT4x3:
|
case GL_FLOAT_MAT4x3:
|
||||||
*r_comp_type = GPU_COMP_F32;
|
*r_comp_type = GPU_COMP_F32;
|
||||||
*r_gl_comp_type = GL_FLOAT;
|
|
||||||
*r_fetch_mode = GPU_FETCH_FLOAT;
|
*r_fetch_mode = GPU_FETCH_FLOAT;
|
||||||
break;
|
break;
|
||||||
case GL_INT:
|
case GL_INT:
|
||||||
@@ -390,7 +336,6 @@ static void get_fetch_mode_and_comp_type(int gl_type,
|
|||||||
case GL_INT_VEC3:
|
case GL_INT_VEC3:
|
||||||
case GL_INT_VEC4:
|
case GL_INT_VEC4:
|
||||||
*r_comp_type = GPU_COMP_I32;
|
*r_comp_type = GPU_COMP_I32;
|
||||||
*r_gl_comp_type = GL_INT;
|
|
||||||
*r_fetch_mode = GPU_FETCH_INT;
|
*r_fetch_mode = GPU_FETCH_INT;
|
||||||
break;
|
break;
|
||||||
case GL_UNSIGNED_INT:
|
case GL_UNSIGNED_INT:
|
||||||
@@ -398,7 +343,6 @@ static void get_fetch_mode_and_comp_type(int gl_type,
|
|||||||
case GL_UNSIGNED_INT_VEC3:
|
case GL_UNSIGNED_INT_VEC3:
|
||||||
case GL_UNSIGNED_INT_VEC4:
|
case GL_UNSIGNED_INT_VEC4:
|
||||||
*r_comp_type = GPU_COMP_U32;
|
*r_comp_type = GPU_COMP_U32;
|
||||||
*r_gl_comp_type = GL_UNSIGNED_INT;
|
|
||||||
*r_fetch_mode = GPU_FETCH_INT;
|
*r_fetch_mode = GPU_FETCH_INT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -424,15 +368,19 @@ void GPU_vertformat_from_interface(GPUVertFormat *format, const GPUShaderInterfa
|
|||||||
format->name_len++; /* multiname support */
|
format->name_len++; /* multiname support */
|
||||||
format->attr_len++;
|
format->attr_len++;
|
||||||
|
|
||||||
|
GPUVertCompType comp_type;
|
||||||
|
GPUVertFetchMode fetch_mode;
|
||||||
|
get_fetch_mode_and_comp_type(input->gl_type, &comp_type, &fetch_mode);
|
||||||
|
|
||||||
GPUVertAttr *attr = &format->attrs[input->location];
|
GPUVertAttr *attr = &format->attrs[input->location];
|
||||||
|
|
||||||
attr->name[attr->name_len++] = copy_attr_name(
|
attr->names[attr->name_len++] = copy_attr_name(format, name_buffer + input->name_offset);
|
||||||
format, name_buffer + input->name_offset, NULL);
|
|
||||||
attr->offset = 0; /* offsets & stride are calculated later (during pack) */
|
attr->offset = 0; /* offsets & stride are calculated later (during pack) */
|
||||||
attr->comp_len = calc_input_component_size(input);
|
attr->comp_len = calc_input_component_size(input);
|
||||||
attr->sz = attr->comp_len * 4;
|
attr->sz = attr->comp_len * 4;
|
||||||
get_fetch_mode_and_comp_type(
|
attr->fetch_mode = fetch_mode;
|
||||||
input->gl_type, &attr->comp_type, &attr->gl_comp_type, &attr->fetch_mode);
|
attr->comp_type = comp_type;
|
||||||
|
attr->gl_comp_type = convert_comp_type_to_gl(comp_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user