vbo/save: avoid dangling_attr_ref situation
dangling_attr_ref=true can be set when the following happens: glBegin(GL_TRIANGLES) glVertex(...) glVertex(...) glColor4(...) glVertex(...) When glColor4 is hit, the first 2 vertices are copied to the vertex_store by upgrade_vertex, but since this is done before glColor4 new values are copied, we make a note to fixup these attribute laters using dangling_attr_ref. This causes very slow rendering. What this commit does instead, is in this situation, the new attribute value are backported to the vertex store for the copied vertices after upgrade_vertex is done updating the layout. This avoids the slow corner case. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7912 Reviewed-by: Marek Olšák <marek.olsak@amd.com> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20495>
This commit is contained in:
committed by
Marge Bot
parent
a9ab06668f
commit
aa1a752979
@@ -1175,7 +1175,9 @@ upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
|
||||
grow_vertex_storage(ctx, save->copied.nr);
|
||||
fi_type *dest = save->vertex_store->buffer_in_ram;
|
||||
|
||||
/* Need to note this and fix up at runtime (or loopback):
|
||||
/* Need to note this and fix up later. This can be done in
|
||||
* ATTR_UNION (by copying the new attribute values to the
|
||||
* vertices we're copying here) or at runtime (or loopback).
|
||||
*/
|
||||
if (attr != VBO_ATTRIB_POS && save->currentsz[attr][0] == 0) {
|
||||
assert(oldsz == 0);
|
||||
@@ -1234,13 +1236,14 @@ upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
|
||||
* For example, after seeing one or more glTexCoord2f() calls we
|
||||
* get a glTexCoord4f() or glTexCoord1f() call.
|
||||
*/
|
||||
static void
|
||||
static bool
|
||||
fixup_vertex(struct gl_context *ctx, GLuint attr,
|
||||
GLuint sz, GLenum newType)
|
||||
{
|
||||
struct vbo_save_context *save = &vbo_context(ctx)->save;
|
||||
bool new_attr_is_bigger = sz > save->attrsz[attr];
|
||||
|
||||
if (sz > save->attrsz[attr] ||
|
||||
if (new_attr_is_bigger ||
|
||||
newType != save->attrtype[attr]) {
|
||||
/* New size is larger. Need to flush existing vertices and get
|
||||
* an enlarged vertex format.
|
||||
@@ -1261,6 +1264,8 @@ fixup_vertex(struct gl_context *ctx, GLuint attr,
|
||||
save->active_sz[attr] = sz;
|
||||
|
||||
grow_vertex_storage(ctx, 1);
|
||||
|
||||
return new_attr_is_bigger;
|
||||
}
|
||||
|
||||
|
||||
@@ -1314,8 +1319,31 @@ do { \
|
||||
struct vbo_save_context *save = &vbo_context(ctx)->save; \
|
||||
int sz = (sizeof(C) / sizeof(GLfloat)); \
|
||||
\
|
||||
if (save->active_sz[A] != N) \
|
||||
fixup_vertex(ctx, A, N * sz, T); \
|
||||
if (save->active_sz[A] != N) { \
|
||||
bool had_dangling_ref = save->dangling_attr_ref; \
|
||||
fi_type *dest = save->vertex_store->buffer_in_ram; \
|
||||
if (fixup_vertex(ctx, A, N * sz, T) && \
|
||||
!had_dangling_ref && save->dangling_attr_ref && \
|
||||
A != VBO_ATTRIB_POS) { \
|
||||
/* Copy the new attr values to the already copied \
|
||||
* vertices. \
|
||||
*/ \
|
||||
for (int i = 0; i < save->copied.nr; i++) { \
|
||||
GLbitfield64 enabled = save->enabled; \
|
||||
while (enabled) { \
|
||||
const int j = u_bit_scan64(&enabled); \
|
||||
if (j == A) { \
|
||||
if (N>0) ((C*) dest)[0] = V0; \
|
||||
if (N>1) ((C*) dest)[1] = V1; \
|
||||
if (N>2) ((C*) dest)[2] = V2; \
|
||||
if (N>3) ((C*) dest)[3] = V3; \
|
||||
} \
|
||||
dest += save->attrsz[j]; \
|
||||
} \
|
||||
} \
|
||||
save->dangling_attr_ref = false; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
{ \
|
||||
C *dest = (C *)save->attrptr[A]; \
|
||||
|
||||
Reference in New Issue
Block a user