vbo: merge more primitive types for glBegin/End (v2)

v2: clean it up more

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4052>
This commit is contained in:
Marek Olšák 2020-02-13 23:22:44 -05:00
parent d740e3d6ee
commit ab7209fb83
4 changed files with 43 additions and 50 deletions

View file

@ -168,14 +168,12 @@ vbo_try_prim_conversion(struct _mesa_prim *p)
/**
* Helper function for determining if two subsequent glBegin/glEnd
* primitives can be combined. This is only possible for GL_POINTS,
* GL_LINES, GL_TRIANGLES and GL_QUADS.
* If we return true, it means that we can concatenate p1 onto p0 (and
* discard p1).
* Function for merging two subsequent glBegin/glEnd draws.
* Return true if p1 was concatenated onto p0 (to discard p1 in the caller).
*/
bool
vbo_can_merge_prims(const struct _mesa_prim *p0, const struct _mesa_prim *p1)
vbo_merge_draws(struct gl_context *ctx, bool in_dlist,
struct _mesa_prim *p0, const struct _mesa_prim *p1)
{
if (!p0->begin ||
!p1->begin ||
@ -193,37 +191,42 @@ vbo_can_merge_prims(const struct _mesa_prim *p0, const struct _mesa_prim *p1)
assert(p0->basevertex == p1->basevertex);
/* can always merge subsequent GL_POINTS primitives */
if (p0->mode == GL_POINTS)
return true;
/* independent lines with no extra vertices */
if (p0->mode == GL_LINES && p0->count % 2 == 0)
return true;
/* independent tris */
if (p0->mode == GL_TRIANGLES && p0->count % 3 == 0)
return true;
/* independent quads */
if (p0->mode == GL_QUADS && p0->count % 4 == 0)
return true;
return false;
}
/**
* If we've determined that p0 and p1 can be merged, this function
* concatenates p1 onto p0.
*/
void
vbo_merge_prims(struct _mesa_prim *p0, const struct _mesa_prim *p1)
{
assert(vbo_can_merge_prims(p0, p1));
switch (p0->mode) {
case GL_POINTS:
/* can always merge subsequent GL_POINTS primitives */
break;
/* check independent primitives with no extra vertices */
case GL_LINES:
if (p0->count % 2)
return false;
break;
case GL_TRIANGLES:
if (p0->count % 3)
return false;
break;
case GL_QUADS:
case GL_LINES_ADJACENCY:
if (p0->count % 4)
return false;
break;
case GL_TRIANGLES_ADJACENCY:
if (p0->count % 6)
return false;
break;
case GL_PATCHES:
/* "patch_vertices" can be unknown when compiling a display list. */
if (in_dlist ||
p0->count % ctx->TessCtrlProgram.patch_vertices)
return false;
break;
default:
return false;
}
/* Merge draws. */
p0->count += p1->count;
p0->end = p1->end;
return true;
}
/**

View file

@ -846,14 +846,8 @@ try_vbo_merge(struct vbo_exec_context *exec)
struct _mesa_prim *prev = &exec->vtx.prim[exec->vtx.prim_count - 2];
assert(prev == cur - 1);
if (vbo_can_merge_prims(prev, cur)) {
assert(cur->begin);
assert(cur->end);
assert(prev->begin);
assert(prev->end);
vbo_merge_prims(prev, cur);
if (vbo_merge_draws(exec->ctx, false, prev, cur))
exec->vtx.prim_count--; /* drop the last primitive */
}
}
}

View file

@ -179,11 +179,8 @@ void
vbo_try_prim_conversion(struct _mesa_prim *p);
bool
vbo_can_merge_prims(const struct _mesa_prim *p0, const struct _mesa_prim *p1);
void
vbo_merge_prims(struct _mesa_prim *p0, const struct _mesa_prim *p1);
vbo_merge_draws(struct gl_context *ctx, bool in_dlist,
struct _mesa_prim *p0, const struct _mesa_prim *p1);
unsigned
vbo_copy_vertices(struct gl_context *ctx,

View file

@ -273,7 +273,7 @@ reset_counters(struct gl_context *ctx)
* previous prim.
*/
static void
merge_prims(struct _mesa_prim *prim_list,
merge_prims(struct gl_context *ctx, struct _mesa_prim *prim_list,
GLuint *prim_count)
{
GLuint i;
@ -284,11 +284,10 @@ merge_prims(struct _mesa_prim *prim_list,
vbo_try_prim_conversion(this_prim);
if (vbo_can_merge_prims(prev_prim, this_prim)) {
if (vbo_merge_draws(ctx, true, prev_prim, this_prim)) {
/* We've found a prim that just extend the previous one. Tack it
* onto the previous one, and let this primitive struct get dropped.
*/
vbo_merge_prims(prev_prim, this_prim);
continue;
}
@ -578,7 +577,7 @@ compile_vertex_list(struct gl_context *ctx)
convert_line_loop_to_strip(save, node);
}
merge_prims(node->prims, &node->prim_count);
merge_prims(ctx, node->prims, &node->prim_count);
/* Correct the primitive starts, we can only do this here as copy_vertices
* and convert_line_loop_to_strip above consume the uncorrected starts.