GPU: Add GPU_vertformat_triple_load to load next vertices attrib

Right now does not add padding at the end of the buffer.

This seems not necessary but may cause problem on some platform. If needed
we will add this padding (only 2 more vertices).
This commit is contained in:
Clément Foucault 2018-12-07 00:58:17 +01:00
parent 88d36e6456
commit fe20aa1edf
Notes: blender-bot 2023-02-14 04:38:07 +01:00
Referenced by issue #58949, Wrong assert check for transfor mfeedback
2 changed files with 63 additions and 6 deletions

View File

@ -92,6 +92,16 @@ uint GPU_vertformat_attr_add(
void GPU_vertformat_alias_add(GPUVertFormat *, const char *alias);
int GPU_vertformat_attr_id_get(const GPUVertFormat *, const char *name);
/**
* This makes the "virtual" attribs with suffixes "0", "1", "2" to access triangle data in the vertex
* shader.
*
* IMPORTANT:
* - 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 */
typedef struct GPUPackedNormal {

View File

@ -128,7 +128,7 @@ uint vertex_buffer_size(const GPUVertFormat *format, uint vertex_len)
return format->stride * vertex_len;
}
static const char *copy_attrib_name(GPUVertFormat *format, const char *name)
static const char *copy_attrib_name(GPUVertFormat *format, const char *name, const char *suffix)
{
/* strncpy does 110% of what we need; let's do exactly 100% */
char *name_copy = format->names + format->name_offset;
@ -139,8 +139,21 @@ static const char *copy_attrib_name(GPUVertFormat *format, const char *name)
const char c = name[i];
name_copy[i] = c;
if (c == '\0') {
terminated = true;
format->name_offset += (i + 1);
if (suffix) {
for (uint j = 0; j < available; ++j) {
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;
}
}
@ -186,7 +199,7 @@ uint GPU_vertformat_attr_add(
const uint attrib_id = format->attr_len++;
GPUVertAttr *attrib = format->attribs + attrib_id;
attrib->name[attrib->name_len++] = copy_attrib_name(format, name);
attrib->name[attrib->name_len++] = copy_attrib_name(format, name, NULL);
attrib->comp_type = comp_type;
attrib->gl_comp_type = convert_comp_type_to_gl(comp_type);
attrib->comp_len = (comp_type == GPU_COMP_I10) ? 4 : comp_len; /* system needs 10_10_10_2 to be 4 or BGRA */
@ -205,7 +218,7 @@ void GPU_vertformat_alias_add(GPUVertFormat *format, const char *alias)
assert(attrib->name_len < GPU_VERT_ATTR_MAX_NAMES);
#endif
format->name_len++; /* multiname support */
attrib->name[attrib->name_len++] = copy_attrib_name(format, alias);
attrib->name[attrib->name_len++] = copy_attrib_name(format, alias, NULL);
}
int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const char *name)
@ -221,6 +234,40 @@ int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const char *name)
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 *attrib = format->attribs + a_idx;
/* Duplicate attrib twice */
for (int i = 1; i < 3; ++i) {
GPUVertAttr *dst_attrib = format->attribs + format->attr_len;
memcpy(dst_attrib, attrib, sizeof(GPUVertAttr));
/* Increase offset to the next vertex. */
dst_attrib->offset += format->stride * i;
/* Only copy first name for now. */
dst_attrib->name_len = 0;
dst_attrib->name[dst_attrib->name_len++] = copy_attrib_name(format, attrib->name[0], (i == 1) ? "1" : "2");
format->attr_len++;
}
#if TRUST_NO_ONE
assert(attrib->name_len < GPU_VERT_ATTR_MAX_NAMES);
#endif
/* Add alias to first attrib. */
format->name_len++;
attrib->name[attrib->name_len++] = copy_attrib_name(format, attrib->name[0], "0");
}
}
uint padding(uint offset, uint alignment)
{
const uint mod = offset % alignment;
@ -380,7 +427,7 @@ void GPU_vertformat_from_interface(GPUVertFormat *format, const GPUShaderInterfa
GPUVertAttr *attrib = format->attribs + input->location;
attrib->name[attrib->name_len++] = copy_attrib_name(format, name_buffer + input->name_offset);
attrib->name[attrib->name_len++] = copy_attrib_name(format, name_buffer + input->name_offset, NULL);
attrib->offset = 0; /* offsets & stride are calculated later (during pack) */
attrib->comp_len = calc_input_component_size(input);
attrib->sz = attrib->comp_len * 4;