vbo: don't store glVertex values temporarily into exec
This improves performance by 4.3% in Viewperf11/Catia, first scene. Reviewed-by: Mathias Fröhlich <mathias.froehlich@web.de> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3766>
This commit is contained in:
@@ -80,6 +80,7 @@ struct vbo_exec_context
|
|||||||
struct gl_buffer_object *bufferobj;
|
struct gl_buffer_object *bufferobj;
|
||||||
|
|
||||||
GLuint vertex_size; /* in dwords */
|
GLuint vertex_size; /* in dwords */
|
||||||
|
GLuint vertex_size_no_pos;
|
||||||
|
|
||||||
struct _mesa_prim prim[VBO_MAX_PRIM];
|
struct _mesa_prim prim[VBO_MAX_PRIM];
|
||||||
GLuint prim_count;
|
GLuint prim_count;
|
||||||
|
@@ -294,7 +294,9 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
|
|||||||
memcpy(old_attrptr, exec->vtx.attrptr, sizeof(old_attrptr));
|
memcpy(old_attrptr, exec->vtx.attrptr, sizeof(old_attrptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(oldSize)) {
|
bool repopulate = unlikely(oldSize) || (attr != 0 && exec->vtx.attr[0].size);
|
||||||
|
|
||||||
|
if (repopulate) {
|
||||||
/* Do a COPY_TO_CURRENT to ensure back-copying works for the
|
/* Do a COPY_TO_CURRENT to ensure back-copying works for the
|
||||||
* case when the attribute already exists in the vertex and is
|
* case when the attribute already exists in the vertex and is
|
||||||
* having its size increased.
|
* having its size increased.
|
||||||
@@ -315,17 +317,21 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
|
|||||||
*/
|
*/
|
||||||
exec->vtx.attr[attr].size = newSize;
|
exec->vtx.attr[attr].size = newSize;
|
||||||
exec->vtx.vertex_size += newSize - oldSize;
|
exec->vtx.vertex_size += newSize - oldSize;
|
||||||
|
exec->vtx.vertex_size_no_pos = exec->vtx.vertex_size - exec->vtx.attr[0].size;
|
||||||
exec->vtx.max_vert = vbo_compute_max_verts(exec);
|
exec->vtx.max_vert = vbo_compute_max_verts(exec);
|
||||||
exec->vtx.vert_count = 0;
|
exec->vtx.vert_count = 0;
|
||||||
exec->vtx.buffer_ptr = exec->vtx.buffer_map;
|
exec->vtx.buffer_ptr = exec->vtx.buffer_map;
|
||||||
exec->vtx.enabled |= BITFIELD64_BIT(attr);
|
exec->vtx.enabled |= BITFIELD64_BIT(attr);
|
||||||
|
|
||||||
if (unlikely(oldSize)) {
|
if (repopulate) {
|
||||||
/* Size changed, recalculate all the attrptr[] values
|
/* Size changed, recalculate all the attrptr[] values
|
||||||
*/
|
*/
|
||||||
fi_type *tmp = exec->vtx.vertex;
|
fi_type *tmp = exec->vtx.vertex;
|
||||||
|
|
||||||
for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
|
/* Iterate backwards to make the position last, because glVertex
|
||||||
|
* expects that.
|
||||||
|
*/
|
||||||
|
for (int i = VBO_ATTRIB_MAX - 1; i >= 0; i--) {
|
||||||
if (exec->vtx.attr[i].size) {
|
if (exec->vtx.attr[i].size) {
|
||||||
exec->vtx.attrptr[i] = tmp;
|
exec->vtx.attrptr[i] = tmp;
|
||||||
tmp += exec->vtx.attr[i].size;
|
tmp += exec->vtx.attr[i].size;
|
||||||
@@ -453,6 +459,19 @@ is_vertex_position(const struct gl_context *ctx, GLuint index)
|
|||||||
_mesa_inside_begin_end(ctx));
|
_mesa_inside_begin_end(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write a 64-bit value into a 32-bit pointer by preserving endianness. */
|
||||||
|
#if UTIL_ARCH_LITTLE_ENDIAN
|
||||||
|
#define SET_64BIT(dst32, u64) do { \
|
||||||
|
*(dst32)++ = (u64); \
|
||||||
|
*(dst32)++ = (uint64_t)(u64) >> 32; \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define SET_64BIT(dst32, u64) do { \
|
||||||
|
*(dst32)++ = (uint64_t)(u64) >> 32; \
|
||||||
|
*(dst32)++ = (u64); \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This macro is used to implement all the glVertex, glColor, glTexCoord,
|
* This macro is used to implement all the glVertex, glColor, glTexCoord,
|
||||||
@@ -476,8 +495,8 @@ do { \
|
|||||||
vbo_exec_fixup_vertex(ctx, A, N * sz, T); \
|
vbo_exec_fixup_vertex(ctx, A, N * sz, T); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/* store vertex attribute in vertex buffer */ \
|
/* store a copy of the attribute in exec except for glVertex */ \
|
||||||
{ \
|
if ((A) != 0) { \
|
||||||
C *dest = (C *)exec->vtx.attrptr[A]; \
|
C *dest = (C *)exec->vtx.attrptr[A]; \
|
||||||
if (N>0) dest[0] = V0; \
|
if (N>0) dest[0] = V0; \
|
||||||
if (N>1) dest[1] = V1; \
|
if (N>1) dest[1] = V1; \
|
||||||
@@ -488,13 +507,32 @@ do { \
|
|||||||
\
|
\
|
||||||
if ((A) == 0) { \
|
if ((A) == 0) { \
|
||||||
/* This is a glVertex call */ \
|
/* This is a glVertex call */ \
|
||||||
GLuint i; \
|
uint32_t *dst = (uint32_t *)exec->vtx.buffer_ptr; \
|
||||||
|
uint32_t *src = (uint32_t *)exec->vtx.vertex; \
|
||||||
|
unsigned vertex_size_no_pos = exec->vtx.vertex_size_no_pos; \
|
||||||
\
|
\
|
||||||
/* copy 32-bit words */ \
|
/* Copy over attributes from exec. */ \
|
||||||
for (i = 0; i < exec->vtx.vertex_size; i++) \
|
for (unsigned i = 0; i < vertex_size_no_pos; i++) \
|
||||||
exec->vtx.buffer_ptr[i] = exec->vtx.vertex[i]; \
|
*dst++ = *src++; \
|
||||||
\
|
\
|
||||||
exec->vtx.buffer_ptr += exec->vtx.vertex_size; \
|
/* Store the position, which is always last and can have 32 or */ \
|
||||||
|
/* 64 bits per channel. */ \
|
||||||
|
if (sizeof(C) == 4) { \
|
||||||
|
if (N > 0) *dst++ = V0; \
|
||||||
|
if (N > 1) *dst++ = V1; \
|
||||||
|
if (N > 2) *dst++ = V2; \
|
||||||
|
if (N > 3) *dst++ = V3; \
|
||||||
|
} else { \
|
||||||
|
/* 64 bits: dst can be unaligned, so copy each 4-byte word */ \
|
||||||
|
/* separately */ \
|
||||||
|
if (N > 0) SET_64BIT(dst, V0); \
|
||||||
|
if (N > 1) SET_64BIT(dst, V1); \
|
||||||
|
if (N > 2) SET_64BIT(dst, V2); \
|
||||||
|
if (N > 3) SET_64BIT(dst, V3); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
/* dst now points at the beginning of the next vertex */ \
|
||||||
|
exec->vtx.buffer_ptr = (fi_type*)dst; \
|
||||||
\
|
\
|
||||||
/* Set FLUSH_STORED_VERTICES to indicate that there's now */ \
|
/* Set FLUSH_STORED_VERTICES to indicate that there's now */ \
|
||||||
/* something to draw (not just updating a color or texcoord).*/ \
|
/* something to draw (not just updating a color or texcoord).*/ \
|
||||||
|
Reference in New Issue
Block a user